Given the XML document
<?xml version="1.0" encoding="utf-8" standalone="no"?> <resources> <!-- Color Scheme --> <color name="primary">#YYYYYY</color> <color name="primary_variant">#ZZZZZZ</color> <color name="primary_variant">#ZZZZZZ</color> <color name="primary_variant_old">#ZZZZZZ</color> <color name="primary_variant_new">#ZZZZZZ</color> </resources>
in file.xml
, you could use the xq
utility to get the output you want like so:
xq -r '.resources.color[] | "val " + ( ."@name" | gsub("_(?<a>.)"; .a | ascii_upcase) ) + " = Color(" + ( ."#text" | sub("#"; "0xFF") ) + ")"' file.xml
or, possibly easier to read,
xq -r '.resources.color[] | [ ( ."@name" | gsub("_(?<a>.)"; .a | ascii_upcase) ), ( ."#text" | sub("#"; "0xFF") ) ] | "val " + .[0] + " = Color(" + .[1] + ")"' file.xml
This picks out each color entry and inserts the modified value of the name
attribute and the color
node's value into a string that is then outputted.
The name
attribute is turned into camel-case by converting each _x
(where x
is any character) into X
(upper-case x
). The color
nodes value then gets its #
replaced by 0xFF
.
This would output
val primary = Color(0xFFYYYYYY) val primaryVariant = Color(0xFFZZZZZZ) val primaryVariant = Color(0xFFZZZZZZ) val primaryVariantOld = Color(0xFFZZZZZZ) val primaryVariantNew = Color(0xFFZZZZZZ)
The xq
utility is a tool for translation of XML into JSON. The xq
tool then becomes a wrapper around the well known jq
JSON parser, so jq
expressions may be used to modify or generally work with the XML document structure. It is part of the yq
utility distribution (originally a YAML parser wrapper around jq
), as found at https://kislyuk.github.io/yq/ (the yq
utility available via snap
on Linux is also a YAML parser, but a quite different tool!)
The xq
parser, like most other parsers, discards comments.
For reference, this is the JSON document that xq
converts the above XML into:
{ "resources": { "color": [ { "@name": "primary", "#text": "#YYYYYY" }, { "@name": "primary_variant", "#text": "#ZZZZZZ" }, { "@name": "primary_variant", "#text": "#ZZZZZZ" }, { "@name": "primary_variant_old", "#text": "#ZZZZZZ" }, { "@name": "primary_variant_new", "#text": "#ZZZZZZ" } ] } }
sed
or alike.sed
orawk
is finexmlstarlet
, or an xml-parsing library for python. 1. shell is good for running and orchestrating programs that do text-processing (and other) work. It is not good (in fact, it is terrible) at actually doing that work itself. 2. simple line-oriented tools like sed or awk, using regular expressions alone, are not adequate for parsing XML or other structure text - awk is capable of it, but you'll probably have to write your own xml parser - whereas other languages, like perl or python, already have parser libs written, tested, readily available, and in use for years.