4

我无法使用简单的 (?) XSLT 转换进行管理。

有一个输入扁平结构的 XML:

<root>
    <attribute_a>abc</attribute_a>
    <attribute_b>def</attribute_b>
    <attribute_c>ghi</attribute_c>
    <attribute_a>123</attribute_a>
    <attribute_b>456</attribute_b>
    <attribute_c>789</attribute_c>
    <attribute_a>xxx</attribute_a>
    <attribute_b>xxx</attribute_b>
    <attribute_c>xxx</attribute_c>
</root>

我应该将它转换为这样的 XML:

<root>
    <attribute>
        <attribute_a>abc</attribute_a>
        <attribute_b>def</attribute_b>
        <attribute_c>ghi</attribute_c>
    </attribute>
    <attribute>
        <attribute_a>123</attribute_a>
        <attribute_b>456</attribute_b>
        <attribute_c>789</attribute_c>
    </attribute>
    <attribute>
        <attribute_a>xxx</attribute_a>
        <attribute_b>xxx</attribute_b>
        <attribute_c>xxx</attribute_c>
    </attribute>
</root>

但问题是在这样的转换之后:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" />

    <xsl:template match="/">
        <root>
            <xsl:for-each select="root/attribute_a">
                <attribute>
                    <attribute_a>
                        <xsl:value-of select="../attribute_a" />
                    </attribute_a>
                    <attribute_b>
                        <xsl:value-of select="../attribute_b" />
                    </attribute_b>
                    <attribute_c>
                        <xsl:value-of select="../attribute_c" />
                    </attribute_c>
                </attribute>
            </xsl:for-each>
        </root>
        <xsl:apply-templates />
    </xsl:template>
</xsl:stylesheet>

我得到了这样的东西:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <attribute>
        <attribute_a>abc</attribute_a>
        <attribute_b>def</attribute_b>
        <attribute_c>ghi</attribute_c>
    </attribute>
    <attribute>
        <attribute_a>abc</attribute_a>
        <attribute_b>def</attribute_b>
        <attribute_c>ghi</attribute_c>
    </attribute>
    <attribute>
        <attribute_a>abc</attribute_a>
        <attribute_b>def</attribute_b>
        <attribute_c>ghi</attribute_c>
    </attribute>
</root>

我在 XSLT 方面不是很有经验 - 你有什么想法吗?:(

问候,上午

4

1 回答 1

2

这应该可以解决问题:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

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

  <xsl:template match="/">
    <root>
      <xsl:for-each select="root/attribute_a">
        <xsl:variable name="pos" select="position()"/>
        <attribute>
          <xsl:apply-templates
            select="../attribute_a[$pos] | 
                    ../attribute_b[$pos] |
                    ../attribute_c[$pos]" />
        </attribute>
      </xsl:for-each>
    </root>
  </xsl:template>
</xsl:stylesheet>

我建议更进一步,使用单独的模板而不是for-each

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

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

  <xsl:template match="/">
    <root>
      <xsl:apply-templates select="root/attribute_a" mode="group" />
    </root>
  </xsl:template>

  <xsl:template match="attribute_a" mode="group">
    <xsl:variable name="pos" select="position()"/>
    <attribute>
      <xsl:apply-templates
        select="../attribute_a[$pos] | ../attribute_b[$pos] | ../attribute_c[$pos]" />
    </attribute>
  </xsl:template>
</xsl:stylesheet>

当这些 XSLT 中的任何一个在您的示例输入上运行时,它都会产生以下输出:

<root>
  <attribute>
    <attribute_a>abc</attribute_a>
    <attribute_b>def</attribute_b>
    <attribute_c>ghi</attribute_c>
  </attribute>
  <attribute>
    <attribute_a>123</attribute_a>
    <attribute_b>456</attribute_b>
    <attribute_c>789</attribute_c>
  </attribute>
  <attribute>
    <attribute_a>xxx</attribute_a>
    <attribute_b>xxx</attribute_b>
    <attribute_c>xxx</attribute_c>
  </attribute>
</root>
于 2013-02-09T21:13:13.023 回答