我正在尝试批量添加大量xml文件的新标记。
示例xml如下:
<attribute name="MyAttribute">
<type>
<long>
<range>
<min>0</min>
<max>100000</max>
</range>
<defaultValue>0</defaultValue>
</long>
</type>
</attribute>
在上面的示例中,我有一个&#34;类型&#34;标记有一定的缩进。我希望能够做到以下几点:
预期结果:
<attribute name="MyAttribute">
<myAddedTag>
<type>
<long>
<range>
<min>0</min>
<max>100000</max>
</range>
<defaultValue>0</defaultValue>
</long>
</type>
</attribute>
我一直在使用sed来查找和替换shell脚本中的类型标签,如下面的命令,但我的问题是缩进 - 我似乎无法弄清楚如何维护它。我试过添加空格,但缩进在所有文件中都不一样。
示例sed命令如下: 文件:my_sample_sed_script.sh
#!/usr/bin/env bash
sed -i "s/<type>/<myAddedTag \/>\n<type>/g" $1
我在bash中使用此命令调用脚本:
my_sed_script.sh sample.xml
但是,输出如下 - 请参阅类型标记没有缩进:
<attribute name="MyAttribute">
<myAddedTag>
<type>
<long>
<range>
<min>0</min>
<max>100000</max>
</range>
<defaultValue>0</defaultValue>
</long>
</type>
</attribute>
任何帮助将不胜感激。正如我所提到的,我的问题是试图找到一个解决方案,使缩进与我复制/替换的行相同。
答案 0 :(得分:2)
您可以使用此sed
,
sed 's/^\(\s\+\)<type>/\1<myAddedTag \/>\n&/g' yourfile
答案 1 :(得分:1)
不要使用sed
来处理XML。
使用像xsltproc
这样的XML-aware工具和这个XSLT样式表:
<!-- add_attribute.xsl -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- copy everything ... -->
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<!-- <attribute name="MyAttribute"> special case -->
<xsl:template match="attribute[@name='MyAttribute']">
<!-- copy element and its attributes -->
<xsl:copy>
<xsl:apply-templates select="@*" />
<!-- copy first, whitespace-only text node (i.e. the indentation) -->
<xsl:copy-of select="text()[1][normalize-space() = '']" />
<!-- add your tag -->
<myAddedTag />
<!-- copy rest of the contents -->
<xsl:apply-templates select="node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
用法:
xsltproc add_attribute.xsl your_file.xml
输出:
<attribute name="MyAttribute">
<myAddedTag/>
<type>
<long>
<range>
<min>0</min>
<max>100000</max>
</range>
<defaultValue>0</defaultValue>
</long>
</type>
</attribute>
好处是结构化破坏XML的可能性为零,而你可以用基本上更易于维护和灵活的方式进行复杂的修改,而不是使用正则表达式。
答案 2 :(得分:0)
如果您愿意为您的任务使用perl或python,则可以使用此方法。
(.+?)(?=(\s*)<type>)(.*)$
试试这个。这保留了缩进。
参见演示。