XSLT:将特定元素移动到新父级

时间:2015-01-23 14:05:27

标签: xml xslt

我在将特定元素从集合移动到新的父节点时遇到问题。我知道如何选择这些元素(这里:msxml的root / order / person [position()> 1])但是无法弄清楚xslt:copy或xslt:copy-of statements的正确用法。

这就是我所拥有的(例如):

<root>
  <order>
    <person>
      ...
    </person>
    <person>
       ...
    </person>
    <person>
       ...
    </person>
  </order>
</root>

我只想将人物元素(1-n)分别放入单个元素中:

<root>
  <order>
    <person>
      ...
    </person>
  </order>
  <order>
    <person>
      ...
    </person>
  </order>
  <order>
    <person>
      ...
    </person>
  </order>
</root>

我已经实现了从order元素中删除除第一个之外的person元素。但现在我无法将剩余的人物元素移动到新创建的订单元素中。

2 个答案:

答案 0 :(得分:0)

  

我知道如何选择这些元素(这里:   root / order / person [position()&gt; 1] for msxml)

     

...

     

我只想将人物元素(1-n)分别放入单个元素中   订单元素:

要么我在这里遗漏了一些东西,要么就是让它变得比它需要的更复杂。尝试:

XSLT 1.0

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

<xsl:template match="/root">
    <root>
        <xsl:for-each select="order/person">
            <order>
                <xsl:copy-of select="."/>
            </order>
        </xsl:for-each>
    </root>
</xsl:template>

</xsl:stylesheet>

或:

XSLT 1.0

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

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

<!-- skip order wrapper -->
<xsl:template match="order">
    <xsl:apply-templates select="@*|node()"/>
</xsl:template>

<!-- add order wrapper to each person -->
<xsl:template match="person">
    <order>
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </order>
</xsl:template>

</xsl:stylesheet>

答案 1 :(得分:0)

我这样做的方法是覆盖身份模板(阅读如何做到这一点)。这使得输入树的复制成为默认行为,除了您覆盖的位。

<!-- import the identity template -->
<xsl:import href="identity.xsl"/>

<!-- this removes the original order element that wrapped the persons -->
<xsl:template match="order">
  <xsl:apply-templates/>
</xsl:template>

<!-- this creates an order element around each person. -->
<xsl:template match="person">
  <order>
    <!-- Because of the identity template override the old person element gets copied here -->
    <xsl:apply-imports/>
  </order>
</xsl:template>