I am using the following the command to extract data from an XML file:
yq -p=xml '.resources.string[] | [.+@name, .+content] | join("|")' sample.xml
With an input XML file like:
<resources>
<string name="String-1">String 1</string>
<string name="String-2">String 2</string>
</resource>
The command works fine with the output:
String-1|String 1
String-2|String 2
But if the input XML file contains only one element:
<resources>
<string name="String-1">String 1</string>
</resource>
The output is just two empty lines.
The input file is read properly and one element, with one attribute and one content, is properly identified, but somehow the values are dropped. If not doing the join operation with the same one element input XML file:
yq -p=xml '.resources.string[] | [.+@name, .+content] ' input.xml
The output is:
[]
[]
It looks like a bug but it could also be some settings I missed. Any workaround or fix?
I am using yq
version v4.34.2
installed with brew on MacOS (Intel) 13.4.1
The problem here is that in your second example, yq
treats resources.string
as a dictionary rather than an array. Compare the output of yq -pxml .resources
between the first example:
string:
- +content: String 1
+@name: String-1
- +content: String 2
+@name: String-2
And the second example:
string:
+content: String 2
+@name: String-2
So for your second example, you can ask for:
$ yyq -pxml -oyml '.resources.string|[.+@name, .+content]|join("|")' < sample2.xml
String-2|String 2
The second example is treated like a dictionary because that's how yq
handles an element with distinct child elements, like:
<cat>
<says>meow</says>
<legs>4</legs>
<cute>true</cute>
</cat>
Which becomes:
cat:
says: meow
legs: "4"
cute: "true"
Looking through the docs there doesn't appear to be a way to enforce the array interpretation when there's a single element.