如何用逗号将xml节点转换为多个节点?

时间:2011-09-19 19:49:47

标签: xml regex xslt

我有一个 1次转换来处理大型XML文件。

我有:

[stuff]
<items>string1,string2,string3,string4</items>
[other stuff]

我想将其替换为:

<itemList>
    <item>string1</item>
    <item>string2</item>
    <item>string3</item>
    <item>string4</item>
</itemList>

我在使用RegEx或XSL之间犹豫不决。我一直试图采用正则表达方式:

搜索

^.*<items>(.*)</items>

替换为

<itemList>\1</itemList>

我坚持“找到逗号并用某些东西替换它们”。我甚至不确定它是否可行......

我怎样才能完成此RegEx?我应该去XSL吗?

2 个答案:

答案 0 :(得分:3)

我会使用XSLT 2.0。

XML输入:

<doc>
  <stuff>sdfsadfsa</stuff>
  <items>string,string,string,string</items>
  <otherstuff>sdfasdfsaf</otherstuff>
</doc>

XSLT 2.0:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="items">
    <itemList>
      <xsl:for-each select="tokenize(.,',')">
        <item><xsl:value-of select="."/></item>
      </xsl:for-each>
    </itemList>
  </xsl:template>

</xsl:stylesheet>

XML输出:

<doc>
   <stuff>sdfsadfsa</stuff>
   <itemList>
      <item>string</item>
      <item>string</item>
      <item>string</item>
      <item>string</item>
   </itemList>
   <otherstuff>sdfasdfsaf</otherstuff>
</doc>

如果您没有XSLT 2.0处理器,我建议Saxon

答案 1 :(得分:1)

因为正则表达式通过单次传递非常糟糕,而且我假设强调的“1次”意味着一次性的努力 - 而不是它必须一举发生(或只有一个表达式) ,我建议两个阶段(我正在使用Perl语法)

第一阶段(将外部标签更改为新标签容器名称):

s!<(/?)items>!<$1itemList>!

第二阶段(解析列出的项目,如果它们在容器中):

s!,([^<,]+)(?=,|</itemList>)|(?<=<itemList>)([^<,]+)(?=,|</itemList>)!\n    <item>$1$2</item>!

这些表达式将生成您需要的内容,但可能无法完全生成您在示例输出中显示的空格。这也假设标签就像你的问题一样简单...如果你变得更复杂(许多不同的名字等等),你应该看看XSLT

如果你想以与示例输出相同的方式对其进行格式化,请在第三次传递时使用最后一个表达式,这将在正确的位置添加额外的回车符:

s!(</item>)(</itemList>)!$1\n$2!