yq/pkg/yqlib/doc/usage/xml.md
Mike Farah ec8ef312ef
Added XML encoding/decoding (#1067)
* Added XML encoding/decoding

* Minor fixes

* Improve yq doc

* Lint
2022-01-15 11:57:59 +11:00

4.5 KiB

XML

Encode and decode to and from XML. Whitespace is not conserved for round trips - but the order of the fields are.

Consecutive xml nodes with the same name are assumed to be arrays.

All values in XML are assumed to be strings - but you can use from_yaml to parse them into their correct types:

yq e -p=xml '.myNumberField |= from_yaml' my.xml
<cat name="tiger">meow</cat>

The content of the node will be set as a field in the map with the key "+content". Use the --xml-content-name flag to change this.

Parse xml: simple

Given a sample.xml file of:

<?xml version="1.0" encoding="UTF-8"?>
<cat>meow</cat>

then

yq e -p=xml '.' sample.xml

will output

cat: meow

Parse xml: array

Consecutive nodes with identical xml names are assumed to be arrays.

Given a sample.xml file of:

<?xml version="1.0" encoding="UTF-8"?>
<animal>1</animal>
<animal>2</animal>

then

yq e -p=xml '.' sample.xml

will output

animal:
  - "1"
  - "2"

Parse xml: attributes

Attributes are converted to fields, with the default attribute prefix '+'. Use '--xml-attribute-prefix` to set your own.

Given a sample.xml file of:

<?xml version="1.0" encoding="UTF-8"?>
<cat legs="4">
  <legs>7</legs>
</cat>

then

yq e -p=xml '.' sample.xml

will output

cat:
  +legs: "4"
  legs: "7"

Parse xml: attributes with content

Content is added as a field, using the default content name of '+content'. Use --xml-content-name to set your own.

Given a sample.xml file of:

<?xml version="1.0" encoding="UTF-8"?>
<cat legs="4">meow</cat>

then

yq e -p=xml '.' sample.xml

will output

cat:
  +content: meow
  +legs: "4"

Parse xml: with comments

A best attempt is made to preserve comments.

Given a sample.xml file of:


<!-- before cat -->
<cat>
	<!-- in cat before -->
	<x>3<!-- multi
line comment 
for x --></x>
	<!-- before y -->
	<y>
		<!-- in y before -->
		<d><!-- in d before -->z<!-- in d after --></d>
		
		<!-- in y after -->
	</y>
	<!-- in_cat_after -->
</cat>
<!-- after cat -->

then

yq e -p=xml '.' sample.xml

will output

# before cat
cat:
  # in cat before
  x: "3" # multi
  # line comment 
  # for x
  # before y

  y:
    # in y before
    # in d before
    d: z # in d after
    # in y after
  # in_cat_after
# after cat

Encode xml: simple

Given a sample.yml file of:

cat: purrs

then

yq e -o=xml '.' sample.yml

will output

<cat>purrs</cat>

Encode xml: array

Given a sample.yml file of:

pets:
  cat:
    - purrs
    - meows

then

yq e -o=xml '.' sample.yml

will output

<pets>
  <cat>purrs</cat>
  <cat>meows</cat>
</pets>

Encode xml: attributes

Fields with the matching xml-attribute-prefix are assumed to be attributes.

Given a sample.yml file of:

cat:
  +name: tiger
  meows: true

then

yq e -o=xml '.' sample.yml

will output

<cat name="tiger">
  <meows>true</meows>
</cat>

Encode xml: attributes with content

Fields with the matching xml-content-name is assumed to be content.

Given a sample.yml file of:

cat:
  +name: tiger
  +content: cool

then

yq e -o=xml '.' sample.yml

will output

<cat name="tiger">cool</cat>

Encode xml: comments

A best attempt is made to copy comments to xml.

Given a sample.yml file of:

# above_cat
cat: # inline_cat
  # above_array
  array: # inline_array
    - val1 # inline_val1
    # above_val2
    - val2 # inline_val2
# below_cat

then

yq e -o=xml '.' sample.yml

will output

<!-- above_cat inline_cat --><cat><!-- above_array inline_array -->
  <array>val1<!-- inline_val1 --></array>
  <array><!-- above_val2 -->val2<!-- inline_val2 --></array>
</cat><!-- below_cat -->

Round trip: with comments

A best effort is made, but comment positions and white space are not preserved perfectly.

Given a sample.xml file of:


<!-- before cat -->
<cat>
	<!-- in cat before -->
	<x>3<!-- multi
line comment 
for x --></x>
	<!-- before y -->
	<y>
		<!-- in y before -->
		<d><!-- in d before -->z<!-- in d after --></d>
		
		<!-- in y after -->
	</y>
	<!-- in_cat_after -->
</cat>
<!-- after cat -->

then

yq e -p=xml -o=xml '.' sample.xml

will output

<!-- before cat --><cat><!-- in cat before -->
  <x>3<!-- multi
line comment 
for x --></x><!-- before y -->
  <y><!-- in y before
in d before -->
    <d>z<!-- in d after --></d><!-- in y after -->
  </y><!-- in_cat_after -->
</cat><!-- after cat -->