使用 XSLT 更改节点的位置

发布于 2024-11-03 13:11:25 字数 904 浏览 1 评论 0原文

我正在使用身份转换,在此期间根据条件,我需要使用 XSLT 更改节点的位置。 假设我有一个如下所示的 XML:

<root>
    <a>
        <b1>SampleB1</b1>
        <b2>
            <c1>zyx</c1>
            <c2>wvu</c2>
            <c3>tsr</c3>
            <c4>dtg</c4>
            <c5>hkj</c5>
        </b2>
        <b3>SampleB3</b3>
    </a>
</root>

然后我想更改节点 'c4' 和 'c4' 的位置。 'c5' 并希望输出为:

<root>
    <c4>dtg</c4>
    <c5>hkj</c5>
    <a>
        <b1>SampleB1</b1>
        <b2>
            <c1>zyx</c1>
            <c2>wvu</c2>
            <c3>tsr</c3>
        </b2>
        <b3>SampleB3</b3>
    </a>
</root>

任何人都可以告诉我,我们怎样才能做到这一点。

谢谢 !!!

I am using identity transformation and during this based on a condition, I need to change the position of a node using XSLT.
Suppose, I have an XML like the one:

<root>
    <a>
        <b1>SampleB1</b1>
        <b2>
            <c1>zyx</c1>
            <c2>wvu</c2>
            <c3>tsr</c3>
            <c4>dtg</c4>
            <c5>hkj</c5>
        </b2>
        <b3>SampleB3</b3>
    </a>
</root>

Then I want to change the position of nodes 'c4' & 'c5' and want output as:

<root>
    <c4>dtg</c4>
    <c5>hkj</c5>
    <a>
        <b1>SampleB1</b1>
        <b2>
            <c1>zyx</c1>
            <c2>wvu</c2>
            <c3>tsr</c3>
        </b2>
        <b3>SampleB3</b3>
    </a>
</root>

Can anyone please tell me, how can we do this.

Thanks !!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

叹沉浮 2024-11-10 13:11:47

要重新排列,您需要调整 XSL,以便它按照您想要的顺序和位置复制您想要的内容。例如:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <!-- At the root element, recurse through any descendant c4 or c5 nodes first -->
    <xsl:template match="root">
        <xsl:copy>
            <xsl:apply-templates select="//c4|//c5"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

    <!-- At the b2 element, copy everything but the C4 or C5 nodes -->
    <xsl:template match="b2">
        <xsl:copy>
            <xsl:apply-templates select="node()[not(self::c4|self::c5)]|@*"/>
        </xsl:copy>
    </xsl:template>

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

</xsl:stylesheet>

To rearrange, you need to adjust your XSL so that it copies what you wants in the order and location that you want it. For example:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <!-- At the root element, recurse through any descendant c4 or c5 nodes first -->
    <xsl:template match="root">
        <xsl:copy>
            <xsl:apply-templates select="//c4|//c5"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

    <!-- At the b2 element, copy everything but the C4 or C5 nodes -->
    <xsl:template match="b2">
        <xsl:copy>
            <xsl:apply-templates select="node()[not(self::c4|self::c5)]|@*"/>
        </xsl:copy>
    </xsl:template>

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

</xsl:stylesheet>
你怎么敢 2024-11-10 13:11:46

纯拉式:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:template match="node()|@*" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="a">
        <xsl:apply-templates mode="search"/>
        <xsl:call-template name="identity"/>
    </xsl:template>
    <xsl:template match="c4|c5"/>
    <xsl:template match="c4|c5" mode="search">
        <xsl:call-template name="identity"/>
    </xsl:template>
    <xsl:template match="text()" mode="search"/>
</xsl:stylesheet>

输出:

<root>
    <c4>dtg</c4>
    <c5>hkj</c5>
    <a>
        <b1>SampleB1</b1>
        <b2>
            <c1>zyx</c1>
            <c2>wvu</c2>
            <c3>tsr</c3>
        </b2>
        <b3>SampleB3</b3>
    </a>
</root>

Pure pull style:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:template match="node()|@*" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="a">
        <xsl:apply-templates mode="search"/>
        <xsl:call-template name="identity"/>
    </xsl:template>
    <xsl:template match="c4|c5"/>
    <xsl:template match="c4|c5" mode="search">
        <xsl:call-template name="identity"/>
    </xsl:template>
    <xsl:template match="text()" mode="search"/>
</xsl:stylesheet>

Output:

<root>
    <c4>dtg</c4>
    <c5>hkj</c5>
    <a>
        <b1>SampleB1</b1>
        <b2>
            <c1>zyx</c1>
            <c2>wvu</c2>
            <c3>tsr</c3>
        </b2>
        <b3>SampleB3</b3>
    </a>
</root>
赠意 2024-11-10 13:11:40

试试这个:

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

  <!-- By default, recursively copy all nodes unchanged -->
  <xsl:template match="@* | node()">
      <xsl:copy>
          <xsl:apply-templates select="@* | node()"/>
      </xsl:copy>
  </xsl:template>

  <!-- But don't copy root/a/b2/c3 and root/a/b2/c4 -->
  <xsl:template match="root/a/b2/c3" />
  <xsl:template match="root/a/b2/c4" />

  <xsl:template match="root">
    <xsl:copy>
      <!-- Place a copy of a/b2/c3 and a/b2/c4 at the start of root -->
      <xsl:copy-of select="a/b2/c3" />
      <xsl:copy-of select="a/b2/c4" />
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

理解上述内容的关键是,它不是移动元素,而是复制元素,然后在其他地方跳过它们。不幸的是,这意味着我们需要指定元素移动两次(一次跳过它们,然后再次在其他地方包含它们的副本),但目前我想不出更简洁的方法。

这个问题 - 使用 XSLT 将子节点移动到父属性 可能也有帮助。

Try this:

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

  <!-- By default, recursively copy all nodes unchanged -->
  <xsl:template match="@* | node()">
      <xsl:copy>
          <xsl:apply-templates select="@* | node()"/>
      </xsl:copy>
  </xsl:template>

  <!-- But don't copy root/a/b2/c3 and root/a/b2/c4 -->
  <xsl:template match="root/a/b2/c3" />
  <xsl:template match="root/a/b2/c4" />

  <xsl:template match="root">
    <xsl:copy>
      <!-- Place a copy of a/b2/c3 and a/b2/c4 at the start of root -->
      <xsl:copy-of select="a/b2/c3" />
      <xsl:copy-of select="a/b2/c4" />
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

The key to understanding the above is that its not moving elements so much as copying elements, and then skipping them elsewhere. Unfortunately this means that we need to specify the elements to move twice (once to skip them and then once again to include a copy of them elsewhere), but at the moment I can't think of a neater way.

This question - Move sub nodes into parent attributes with XSLT might also be helpful.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文