英文:
xmlstarlet add string "null" to self-closing tag
问题
我正在尝试从(Service-Now的REST API)返回的数据中创建一个sqlite3加载器,但它在其xml返回中使用了自闭标签。
如果我能将字段从空的自闭标签转换为带有新值“null”的开放和闭合对,那么我就可以解析该字符串,如果该字段是数组的一部分。
[ 当前 ]
```xml
# 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>
[ 期望 ]
# 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>
已经做了很多搜索,但是使用(sed)等实用工具进行替换我认为不是正确的方法。
如果我不能放置一些东西在那里,我就不能测试它。如果返回可能包含许多正面的结果,测试状态是否失败将不起作用。
# 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
英文:
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
答案1
得分: 1
你可以在 xmlstarlet 中使用 xslt,例如使用以下 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="*"/>
<!-- 默认复制模板 -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!--
匹配没有子节点的元素的模板:text() 和 element() 都是节点
-->
<xsl:template match="*[not(node())]">
<xsl:copy>
<xsl:text>null</xsl:text>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
英文:
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>
答案2
得分: 1
以下xmlstarlet命令实现您的需求。ed
选项用于1)查找所有没有任何内容的元素,2)将文本“null”添加到它们中。
xmlstarlet ed -u "//*[not(node())]" -v "null" test.xml
请注意,这不仅捕获自闭合元素;它捕获所有空元素。从XML的角度来看,<x/>
和<x></x>
是等价的。
英文:
The following xmlstarlet command does what you want. The ed
option is used to 1) find all elements that don't have any content and 2) add the text "null" to them.
xmlstarlet ed -u "//*[not(node())]" -v "null" test.xml
Note that this does not capture just self-closing elements; it captures all empty elements. From an XML point of view, <x/>
and <x></x>
are equivalent.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论