2

このフラットな XML は、レベル フィールドを使用してツリー構造を表します。ツリーのより深いところにある特定のノードの要素を同じブランチにのみ取得するにはどうすればよいですか?

したがって、会社名がAであり、会社BとCを取得する必要があります(別の支店にあるEではありません)。

<Companies>
      <Company>
        <Name>A</Name>
        <Level>0</Level>
      </Company>
      <Company>
        <Name>B</Name>
        <Level>1</Level>
      </Company>
      <Company>
        <Name>C</Name>
        <Level>1</Level>
      </Company>
      <Company>
        <Name>D</Name>
        <Level>0</Level>
      </Company>
      <Company>
        <Name>E</Name>
        <Level>1</Level>
      </Company>
    </Companies>

レベル 1 以上の場合があります。それも返してほしい。XLST1.0を使用しています。

4

4 に答える 4

2

使用:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kDescendants" match="Company[Level > 0]"
  use="generate-id(preceding-sibling::Company[Level=0][1])"/>

 <xsl:template match="/">
     <xsl:copy-of select="key('kDescendants', generate-id(/*/*[Name='A']))"/>
 </xsl:template>
</xsl:stylesheet>

この変換が提供された XML ドキュメントに適用されると、次のようになります。

<Companies>
    <Company>
        <Name>A</Name>
        <Level>0</Level>
    </Company>
    <Company>
        <Name>B</Name>
        <Level>1</Level>
    </Company>
    <Company>
        <Name>C</Name>
        <Level>1</Level>
    </Company>
    <Company>
        <Name>D</Name>
        <Level>0</Level>
    </Company>
    <Company>
        <Name>E</Name>
        <Level>1</Level>
    </Company>
</Companies>

必要な正しい結果が生成されます。

<Company>
   <Name>B</Name>
   <Level>1</Level>
</Company>
<Company>
   <Name>C</Name>
   <Level>1</Level>
</Company>

説明:

キー"kDescendants"は、ツリーの最上位ノードとその子孫の間のマッピングを定義しgenerate-id($someTopNode)ます$someTopNode

于 2012-10-17T13:55:15.227 に答える
0

これは私の試みですが、もっと簡単な方法があると思います...申し訳ありませんが、これは XSLT 2.0 のみです。

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/Companies">
        <xsl:param name="nodeName" select="'A'" />

        <xsl:variable name="level" select="Company[Name = $nodeName]/Level/text()" as="xs:int"/>
        <xsl:variable name="seq" as="node()*" select="Company[Name = $nodeName]/following-sibling::*" />
        <xsl:variable name="levels" as="xs:int*" select="$seq/Level/text()" />
        <xsl:copy-of select="subsequence($seq, 0, index-of($levels, $level)[1])" />
    </xsl:template>
</xsl:stylesheet>
于 2012-10-17T13:32:09.150 に答える
0

フォーカス ノード (current()) が計算の基礎であるとします。

定義...

<xsl:variable name="set1" select="following-sibling::Company[ Level &gt; current()]" />
<xsl:variable name="set2" select="following-sibling::Company[ Level &lt; 
      preceding-sibling::Company[1]/Level][1]/preceding-sibling::Company" />

次に、子会社はこれら 2 つのセットの交差点にあり、これは...

$set1[. = $set2]
于 2012-10-17T12:48:07.343 に答える