解析 XML 文件并根据现有密钥添加新密钥
Parsing an XML file and adding a new key based on an existing key
我真的很想在 bash 中寻求一些关于解决此问题的最佳方法的建议。
我有一个 XML 文件,其中包含 1000 个条目,如下所示:
<?xml version="1.0"?>
<myList>
<dataitem>
<path>./5553 Subset 43d.zip</path>
<name>5553 Subset 43d</name>
</dataitem>
<dataitem>
<path>./Another file name here with spaces.zip</path>
<name>Another file name here with spaces</name>
</dataitem>
...
并且我想使用扩展名为 mp4 的 <name>
密钥数据为每个 <dataitem>
添加一个附加密钥,因此它看起来像这样:
<?xml version="1.0"?>
<myList>
<dataitem>
<path>./5553 Subset 43d.zip</path>
<name>5553 Subset 43d</name>
<video>5553 Subset 43d.mp4</video>
</dataitem>
<dataitem>
<path>./Another file name here with spaces.zip</path>
<name>Another file name here with spaces</name>
<video>Another file name here with spaces.mp4</video>
</dataitem>
...
使用xmlstarlet
工具的正确方法:
xmlstarlet ed -s "//dataitem" -t elem -n video input.xml \
| xmlstarlet ed -u "//dataitem/video" -x "concat(./preceding-sibling::name/text(), '.mp4')"
输出应为:
<?xml version="1.0"?>
<myList>
<dataitem>
<path>./5553 Subset 43d.zip</path>
<name>5553 Subset 43d</name>
<video>5553 Subset 43d.mp4</video>
</dataitem>
<dataitem>
<path>./Another file name here with spaces.zip</path>
<name>Another file name here with spaces</name>
<video>Another file name here with spaces.mp4</video>
</dataitem>
...
或者,考虑 XSLT, the special-purpose language designed to transform XML, with a bash call to xsltproc。
XSLT (另存为.xsl文件,特殊的.xml文件)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="dataitem">
<xsl:copy>
<xsl:copy-of select="*"/>
<video><xsl:value-of select="concat(name, '.mp4')"/></video>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Bash (假设本地 cd 路径,使用已安装的 xsltproc)
xsltproc -o Output.xml XSLTScript.xsl Input.xml
我真的很想在 bash 中寻求一些关于解决此问题的最佳方法的建议。
我有一个 XML 文件,其中包含 1000 个条目,如下所示:
<?xml version="1.0"?>
<myList>
<dataitem>
<path>./5553 Subset 43d.zip</path>
<name>5553 Subset 43d</name>
</dataitem>
<dataitem>
<path>./Another file name here with spaces.zip</path>
<name>Another file name here with spaces</name>
</dataitem>
...
并且我想使用扩展名为 mp4 的 <name>
密钥数据为每个 <dataitem>
添加一个附加密钥,因此它看起来像这样:
<?xml version="1.0"?>
<myList>
<dataitem>
<path>./5553 Subset 43d.zip</path>
<name>5553 Subset 43d</name>
<video>5553 Subset 43d.mp4</video>
</dataitem>
<dataitem>
<path>./Another file name here with spaces.zip</path>
<name>Another file name here with spaces</name>
<video>Another file name here with spaces.mp4</video>
</dataitem>
...
使用xmlstarlet
工具的正确方法:
xmlstarlet ed -s "//dataitem" -t elem -n video input.xml \
| xmlstarlet ed -u "//dataitem/video" -x "concat(./preceding-sibling::name/text(), '.mp4')"
输出应为:
<?xml version="1.0"?>
<myList>
<dataitem>
<path>./5553 Subset 43d.zip</path>
<name>5553 Subset 43d</name>
<video>5553 Subset 43d.mp4</video>
</dataitem>
<dataitem>
<path>./Another file name here with spaces.zip</path>
<name>Another file name here with spaces</name>
<video>Another file name here with spaces.mp4</video>
</dataitem>
...
或者,考虑 XSLT, the special-purpose language designed to transform XML, with a bash call to xsltproc。
XSLT (另存为.xsl文件,特殊的.xml文件)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="dataitem">
<xsl:copy>
<xsl:copy-of select="*"/>
<video><xsl:value-of select="concat(name, '.mp4')"/></video>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Bash (假设本地 cd 路径,使用已安装的 xsltproc)
xsltproc -o Output.xml XSLTScript.xsl Input.xml