使用xmlstarlet生成合法XML:为查询结果添加根节点
使用xmlstarlet筛选XML并输出合法带根节点的结果
问题描述
需要用xmlstarlet从大型XML文件中筛选指定类型的记录,要求输出合法XML格式。当前执行的命令仅能提取目标元素,但输出缺少根节点,无法被要求合法XML的软件正常处理。
当前执行命令:
xmlstarlet sel -t -c "//record[@type='TypeA']" frage.xml
待处理的frage.xml内容:
<?xml version="1.0" encoding="UTF-8"?> <records> <record type="TypeA">uqw8hY7V</record> <record type="TypeB">bN4mT0zL</record> <record type="TypeA">K6p4gJv2</record> <record type="TypeB">z8wQ9xV1</record> <record type="TypeA">a3rL7kY9</record> <record type="TypeB">m1W2pX4e</record> <record type="TypeA">y8T6r5zQ</record> <record type="TypeB">k9pJ2wT3</record> <record type="TypeA">d7V1gL5b</record> <record type="TypeB">t4Y6n0pM</record> </records>
当前输出(无合法根节点):
<record type="TypeA">uqw8hY7V</record><record type="TypeA">K6p4gJv2</record><record type="TypeA">a3rL7kY9</record><record type="TypeA">y8T6r5zQ</record><record type="TypeA">d7V1gL5b</record>
解决方案
方法1:直接构造根节点输出
通过-o参数手动输出根节点的起始和结束标签,同时插入目标元素:
xmlstarlet sel -t -o "<records>" -n -c "//record[@type='TypeA']" -n -o "</records>" frage.xml
参数说明:
-o "<records>":输出根节点起始标签-n:添加换行(可选,优化可读性)-c "//record[@type='TypeA']":提取并复制目标record元素-o "</records>":输出根节点结束标签
输出结果:
<records> <record type="TypeA">uqw8hY7V</record> <record type="TypeA">K6p4gJv2</record> <record type="TypeA">a3rL7kY9</record> <record type="TypeA">y8T6r5zQ</record> <record type="TypeA">d7V1gL5b</record> </records>
方法2:复用原根节点结构
直接匹配包含目标元素的根节点,自动保留完整结构:
xmlstarlet sel -t -c "/records[record[@type='TypeA']]" frage.xml
该命令会保留原XML的声明和根节点,仅保留符合条件的record元素,输出结果:
<?xml version="1.0" encoding="UTF-8"?> <records> <record type="TypeA">uqw8hY7V</record> <record type="TypeA">K6p4gJv2</record> <record type="TypeA">a3rL7kY9</record> <record type="TypeA">y8T6r5zQ</record> <record type="TypeA">d7V1gL5b</record> </records>
方法3:使用XSLT模板实现更灵活控制
如果需要自定义输出格式(比如缩进、额外节点),可以编写XSLT模板:
- 创建
filter.xsl文件:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <records> <xsl:copy-of select="//record[@type='TypeA']"/> </records> </xsl:template> </xsl:stylesheet>
- 执行转换命令:
xmlstarlet tr filter.xsl frage.xml
此方法会生成格式规范的合法XML,支持更多自定义需求。
内容的提问来源于stack exchange,提问作者DrSvanHay
相关产品推荐
相关产品推荐

