我有大量的 xml 文档,其中包含大量不同的标签。我需要更改表单的所有标签,<foo>
并将它们转换为表单<field name="foo">
的标签,同时忽略给定标签的属性。也就是表单的一个标签<foo id="bar">
也要改成标签<field name="foo">
。
为了使这种转换起作用,我还需要区分<foo>
and </foo>
,</foo>
必须去</field>
。
我在 bash 脚本中玩过 sed,但无济于事。
尽管 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>
Sed 不适合这项工作 - 一个简单的 XSL 转换可以更可靠地做到这一点:
<?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>