根据元素级别处理和返回输出

时间:2017-11-29 15:37:07

标签: xml xslt xslt-1.0

我正在尝试将输出返回的位置转换为xml中每个元素的xpath。

这是我的示例xml

<NodeRoot>
    <NodeA class="3">
        <NodeB xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true">
            <NodeC abc="1">103</NodeC>
            <NodeD>103</NodeD>
        </NodeB>
    </NodeA>
    <NodeA class="1">
        <NodeGroup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true">
            <NodeC name="z" asc="2">103</NodeC>
        </NodeGroup>
    </NodeA>
</NodeRoot>

我的XSL

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" encoding="utf-8" media-type="text/plain"/>

    <xsl:template match="@*|text()|comment()|processing-instruction()"/>
    <xsl:template match="@xsi:nil" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>

    <xsl:template match="*">
        <xsl:for-each select="ancestor-or-self::*">
            <xsl:value-of select="concat('/',local-name(.))"/>
        </xsl:for-each>
        <xsl:text>&#xA;</xsl:text>
        <xsl:apply-templates/>
    </xsl:template>
</xsl:stylesheet>

这给了我以下输出

/NodeRoot
/NodeRoot/NodeA
/NodeRoot/NodeA/NodeB
/NodeRoot/NodeA/NodeB/NodeC
/NodeRoot/NodeA/NodeB/NodeD
/NodeRoot/NodeA
/NodeRoot/NodeA/NodeGroup
/NodeRoot/NodeA/NodeGroup/NodeC

返回xpath,但返回的顺序不是我想要的。目前,订单是父级,后跟其所有子级。我想要的是订单的方式是我根据节点的深度得到结果。因此,应返回第一个根(级别0),然后返回其直接子级(级别1元素),然后返回级别2子节点,依此类推。

预期结果

/NodeRoot
/NodeRoot/NodeA
/NodeRoot/NodeA
/NodeRoot/NodeA/NodeB
/NodeRoot/NodeA/NodeGroup
/NodeRoot/NodeA/NodeB/NodeC
/NodeRoot/NodeA/NodeB/NodeD
/NodeRoot/NodeA/NodeGroup/NodeC

所以基本上

All level 0 elements
All level 1 elements
.
.
.
All level n elements

1 个答案:

答案 0 :(得分:1)

因此,不是递归模板处理所有按祖先计数的元素:

mmap

http://xsltransform.hikmatu.com/jyyiVhh

一个简单的<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="text" encoding="utf-8" media-type="text/plain"/> <xsl:template match="/"> <xsl:apply-templates select="//*"> <xsl:sort select="count(ancestor::*)"/> </xsl:apply-templates> </xsl:template> <xsl:template match="*"> <xsl:for-each select="ancestor-or-self::*"> <xsl:value-of select="concat('/',local-name(.))"/> </xsl:for-each> <xsl:text>&#xA;</xsl:text> </xsl:template> </xsl:transform> 将选择文档中的所有元素以按文档顺序进行处理,但是使用嵌套的<xsl:apply-templates select="//*"/>处理顺序会更改,并且首先处理具有最低祖先计数的处理顺序。请参阅https://www.w3.org/TR/xslt-10/#section-Applying-Template-Rules,其中说明“所选节点集按文档顺序处理,除非存在排序规范”和https://www.w3.org/TR/xslt-10/#sorting,其中说明“当模板由xsl实例化时:apply-templates ... ,当前节点列表列表包含按排序顺序处理的完整节点列表“。