XSLT 1.0逻辑拆分元素

时间:2014-01-14 05:31:57

标签: xml xslt xslt-1.0

Loop-1,2和3元素是无界的。下面是输入xml,首先是所有LOOP-1元素,然后是Loop-2元素。 我们如何将其转换为类似输出xml。我尝试在xslt下面但是它给出了相同的输入。

输入xml:

<root>
<LOOP-1><!-- unbounded -->
<element1>A</element1>
</LOOP-1>
<LOOP-1>
<element1>A</element1>
</LOOP-1>

<LOOP-2><!-- unbounded -->
<element2>B</element2>
</LOOP-2>

<LOOP-2>
<element2>B</element2>
</LOOP-2>

</root>

XSLT:

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

<xsl:template match="/">
    <xsl:copy-of select="."/>
</xsl:template>

</xsl:stylesheet>

输出:

<?xml version="1.0"?>
<root>
<LOOP-1> 
<element1>A</element1>
</LOOP-1>
<LOOP-2> 
<element2>B</element2>
</LOOP-2>
<LOOP-1>
<element1> A</element1>
</LOOP-1>
<LOOP-2>
<element2>B</element2>
</LOOP-2>
</root>

2 个答案:

答案 0 :(得分:0)

您可以尝试以下代码:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output 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="child::LOOP-1">
            <xsl:variable name="pos" select="position()"/>
            <xsl:copy>
                <xsl:apply-templates/>
            </xsl:copy>
            <xsl:apply-templates select="following-sibling::LOOP-2[position()=$pos]"/>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:0)

如果您想要处理任意数量的 LOOP 元素(您在第一句中提到1,2和3,但在您的示例中实际上没有显示3),那么您可以做什么定义一个键,以帮助根据他们的“数字”查找元素。

<xsl:key name="loop" match="*[starts-with(local-name(), 'LOOP')]" use="substring-after(local-name(), '-')" />

然后,您只需选择 LOOP-1 元素

即可开始
<xsl:apply-templates select="key('loop', '1')" />

接下来,您将拥有一个共享模板,以匹配任何 LOOP 元素,无论数字

在此范围内,您可以调用身份模板来复制元素,然后使用apply-templates选择带有下一个数字的 LOOP 元素,但是一个位于相同位置:

 <xsl:apply-templates select="key('loop', string(number(substring-after(local-name(), '-')) + 1))[$pos]" />

试试这个XSLT

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

  <xsl:key name="loop" match="*[starts-with(local-name(), 'LOOP')]" use="substring-after(local-name(), '-')" />

  <xsl:template match="root">
    <root>
      <xsl:apply-templates select="key('loop', '1')" />
    </root>
  </xsl:template>

  <xsl:template match="*[starts-with(local-name(), 'LOOP')]">
     <xsl:call-template name="identity" />
     <xsl:variable name="pos" select="position()" />
     <xsl:apply-templates select="key('loop', string(number(substring-after(local-name(), '-')) + 1))[$pos]" />
  </xsl:template>

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