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

XSLT: move specific elements into new parent

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

这是我的(例如):

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

而我只是想将 person 元素 (1-n) 分别放入一个 order 元素中:

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

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

I know how to select these elements (here: root/order/person[position() > 1] for msxml)

...

And I just want to put the person elements (1-n) each into a single order element:

要么是我遗漏了一些东西,要么是你把它弄得比需要的更复杂了。尝试:

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>

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

<!-- 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>