我有大量的xml文档,其中包含大量不同的标记。我需要更改表单<foo>
的所有标记,并将其转换为<field name="foo">
形式的标记,其方式也会忽略给定标记的属性。也就是说,<foo id="bar">
形式的标记也应更改为标记<field name="foo">
。
为了让这种转变发挥作用,我还需要区分<foo>
和</foo>
,因为</foo>
必须转到</field>
。
我在bash脚本中玩过sed,但无济于事。
答案 0 :(得分:3)
虽然sed并不适合这项任务(参见评论;进一步阅读:常规,无上下文语法和xml),但它可以投入使用。试试这个单行:
sed -e 's/<\([^>\/\ ]*\)[^>]*>/<field name=\"\1\">/g' -e 's/<field name=\"\">/<\/field>/g' file
首先,它会用</field>
替换所有结束标记,然后用<field name="firstStoredWord">
此解决方案打印标准输出上的所有内容。如果要在处理时直接将其替换为文件,请尝试
sed -i -e 's/<\([^>\/\ ]*\)[^>]*>/<field name=\"\1\">/g' -e 's/<field name=\"\">/<\/field>/g' file
这来自
<html>
<person>
but <person name="bob"> and <person name="tom"> would both become
</person>
此
<field name="html">
<field name="person">
but <field name="person"> and <field name="person"> would both become
</field>
答案 1 :(得分:0)
Sed是错误的工具 - 简单的XSL Transform可以更可靠地完成这项工作:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="foo">
<field name="foo">
<xsl:apply-templates/>
</field>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
请注意,与sed不同,它可以处理短空元素,标记内的换行符(例如,由某些工具生成),以及几乎任何格式良好的XML。这是我的测试文件:
<?xml version="1.0"?>
<doc>
<section>
<foo>Plain foo, simple content</foo>
</section>
<foo attr="0">Foo with attr, with content
<bar/>
<foo attr="shorttag"/>
</foo>
<foo
attr="1"
>multiline</foo
>
<![CDATA[We mustn't transform <foo> in here!]]>
</doc>
由上述(使用xsltproc 16970175.xslt 16970175.xml
)转换为:
<?xml version="1.0"?>
<doc>
<section>
<field name="foo">Plain foo, simple content</field>
</section>
<field name="foo">Foo with attr, with content
<bar/>
<field name="foo"/>
</field>
<field name="foo">multiline</field>
We mustn't transform <foo> in here!
</doc>