如何使用 XSLT 来排列节点层次结构? [英] How can I use XSLT to permutate a node hierarchy?
问题描述
首先:我完全是XSLT
的初学者.在一个项目中,我们以更抽象的方式合成树转换.对于概念证明,我还尝试将域扩展到简单的 XSLT
.
First of all: I'm a total beginner with XSLT
. In a project we are synthesizing tree transformations in a more abstract manner. For a proof of concept I am trying to extend the domain also to simple XSLT
.
但让我们看一个例子,我的 XML 文档中有几个叶子,如下所示:
But let's just look at one example, I have several leaves in my XML document, like in here:
<input>
<a>
<b>
<c>Foo </c>
<c>Bar </c>
</b>
</a>
<x>
<y>
<z>Foobar </z>
</y>
</x>
</input>
对于我想做的事情,查看路径更容易.a/b/c/Foo
、a/b/c/Bar
、/x/y/z/Foobar
For what I want to do, it's easier to look at the paths.
a/b/c/Foo
, a/b/c/Bar
, /x/y/z/Foobar
我想要做的是根据路径中的索引更改层次结构.例如我想先按顺序:第三级,第一级,第二级.对于上面提到的路径:c/a/b/Foo
、/c/a/b/Bar
、/z/x/y/Foobar代码>.
What I want to do is to change the hierarchy based on the index in the path. For example I want to first have it in the order: third level, first level, second level. For the paths mentioned above: c/a/b/Foo
, /c/a/b/Bar
, /z/x/y/Foobar
.
我的方法是这样的:
<xsl:template name="leaf">
<xsl:copy>
<!-- copy attributes-->
<xsl:copy-of select="@*" />
<!-- take another level-->
<xsl:copy select="../"/>
</xsl:copy>
</xsl:template>
但显然,当我在
中时,我不能再使用../"来获取父元素.我正在寻找任何解决方案来获得这种转换.要么使用完全不同的方法(我对 XSLT 的看法非常狭隘),要么调整我的方法.
But apparently when I'm in a <copy>
I cannot use "../" anymore to get the parent element. I'm looking for any solution to get those kind of transformations. Either by using a completely different (my perspective on XSLT is really narrow) or by tweaking my approach.
<output>
<c>
<a>
<b>Bar</b>
</a>
</c>
<c>
<a>
<b>Foo</b>
</a>
</c>
<z>
<x>
<y>Foobar</y>
<x>
<z>
</output>
附加信息
- 输入 XML 的深度始终为 3(不包括 )
<input>
<one>
<two>
<three>
bla
</three>
</two>
<two>
<three>
blub
</three>
</two>
</one>
</input>
<output>
<three>
<one>
<second>bla</second>
</one>
<one>
<second>blub</second>
</one>
</three>
</output>
我仍然不确定我是否明确说明了我想要实现的转变.也许这个想法会有所帮助:想象一下,我完全分解了输入的 XML:对于每个叶子,考虑叶子本身和叶子的路径,然后根据规则(第三、第一、第二)转换路径.
I'm still not sure if I made clear what transformation I want to achieve. Maybe this idea would help: Imagine that I totally decompose the input XML: for every leaf consider the leaf itself and the path to the leaf and then just transform the path according to the rule (third, first, second).
推荐答案
这不是一个非常优雅的方法,但它有效:
This is not a very elegant approach, but it works:
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="*"/>
<xsl:template match="/input">
<output>
<xsl:apply-templates select="*/*/*/text()"/>
</output>
</xsl:template>
<xsl:template match="text()">
<xsl:element name="{name(ancestor::*[1])}">
<xsl:element name="{name(ancestor::*[3])}">
<xsl:element name="{name(ancestor::*[2])}">
<xsl:copy-of select="."/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
这篇关于如何使用 XSLT 来排列节点层次结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!