0

我有大量的 xml 文档,其中包含大量不同的标签。我需要更改表单的所有标签,<foo>并将它们转换为表单<field name="foo">的标签,同时忽略给定标签的属性。也就是表单的一个标签<foo id="bar">也要改成标签<field name="foo">

为了使这种转换起作用,我还需要区分<foo>and </foo></foo>必须去</field>

我在 bash 脚本中玩过 sed,但无济于事。

4

2 回答 2

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>
于 2013-06-06T19:50:36.413 回答
0

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 &lt;foo&gt; in here!
</doc>
于 2015-12-02T15:05:11.637 回答