2017-11-29 7 views
0

xmlの各要素の出力がxpathsとして返される場所を変換しようとしています。ここで 要素レベルに基づく処理と戻り値

は私のサンプル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

ので、代わりの再帰的なテンプレートプロセス祖先の数によってソートされたすべての要素:

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

http://xsltransform.hikmatu.com/jyyiVhh

シンプルな<xsl:apply-templates select="//*"/>は、ドキュメント内のすべての要素をドキュメント順で処理するように選択しますが、ネストされた<xsl:sort select="count(ancestor::*)"/>では処理順序が変更され、祖先が最も少ないものが最初に処理されます。 「選択されたノードのセットは、ソートの指定がないかぎり、ドキュメントの順序で処理されます」とhttps://www.w3.org/TR/xslt-10/#sortingと表示されているhttps://www.w3.org/TR/xslt-10/#section-Applying-Template-Rulesを参照してください。「テンプレートがxsl:apply-templates ...によってインスタンス化されると、ソートされた順序で処理されているノードの完全なリスト」を参照してください。

+0

ありがとうございます。しかし、私はxsltをデバッグすると、変換がレベルで起こることがわかりますが、私の理解から、最初にxpathが作成され、その位置に基づいてソートされます。しかし、変換は出力の順序をどのように変えるのでしょうか?もう少し詳しく説明すると素晴らしいでしょう。 – asd123

関連する問題