如何使用 XSLT 来排列节点层次结构? [英] How can I use XSLT to permutate a node hierarchy?

查看:32
本文介绍了如何使用 XSLT 来排列节点层次结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先:我完全是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/Fooa/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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆