I am trying to create an sqlite3 loader from data returned from ( Service-Now's REST API ) but it uses self closing tags in it's xml return.
If I could convert the fields from empty self closing to an opening and closing pair with a new value of "null" then I could parse the string if the field was part of an array.
[ CURRENT ]
# cat test.xml | xmllint --format -
<?xml version="1.0" encoding="UTF-8"?>
<response>
<result>
<serial_number>
<display_value>6W5QY03</display_value>
<value>6W5QY03</value>
</serial_number>
<location>
<display_value/>
<value/>
</location>
</result>
</response>
[ DESIRED ]
# cat test.xml | xmllint --format -
<?xml version="1.0" encoding="UTF-8"?>
<response>
<result>
<serial_number>
<display_value>6W5QY03</display_value>
<value>6W5QY03</value>
</serial_number>
<location>
<display_value>null<display_value/>
<value>null<value/>
</location>
</result>
</response>
Have done a lot of searching but substitution with utilities like ( sed ) I don't think is the way to go.
If I can't put something there I can't test for it. If the return could contain many positive returns one failure testing for status would not work.
# cat test.xml
<?xml version="1.0" encoding="UTF-8"?>
<response>
<result>
<serial_number>
<display_value>6W5QY03</display_value>
<value>6W5QY03</value>
</serial_number>
<location>
<display_value/>
<value/>
</location>
</result>
</response>
# xmlstarlet sel -T -t -v "response/result/location/display_value/text()" test.xml
# echo $?
1
# xmlstarlet sel -T -t -v "response/result/serial_number/display_value/text()" test.xml
6W5QY03
# echo $?
0
You could use xslt in xmlstarlet i.e. with this xslt:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- Default copy template -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!--
Template that matches a element that has no node():
text() en element() are both nodes
-->
<xsl:template match="*[not(node())]">
<xsl:copy>
<xsl:text>null</xsl:text>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>