2012-02-24 20 views
2

を取得できません:は、私はこのようなXMLを持って正しいXSLT出力

<?xml version="1.0" encoding="UTF-8"?> 
<Section> 
    <Chapter> 
     <nametable> 
      <namerow> 
       <namecell stuff="1"> 
        <entity>A</entity> 
       </namecell> 
       <namecell stuff="2"> 
        <entity>B</entity> 
       </namecell> 
      </namerow> 
     </nametable> 
    </Chapter> 
</Section> 

私のXSLTは、このようなものです:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="2.0"> 

<xsl:output method="text"/> 

    <xsl:template match="/"> 
     <xsl:apply-templates select="Section/Chapter//nametable"/> 
    </xsl:template> 

    <xsl:template match="nametable"> 
     <xsl:for-each select="./namerow"> 
      <xsl:value-of select="./namecell/@stuff"/> 
      <xsl:value-of select="./namecell" /> 
     </xsl:for-each> 
    </xsl:template> 

<xsl:template match="text()"/> 

</xsl:stylesheet> 

奇数が、私はこの順序で出力を取得しています1 2 AB、私は1 A 2 Bを得るつもりだと思った。

なぜそれが分かっていますか?

TIA、

ジョン

答えて

3

あなたの問題はここにです:そのselect属性で指定されたシーケンスの

 <xsl:for-each select="./namerow"> 
      <xsl:value-of select="./namecell/@stuff"/> 
      <xsl:value-of select="./namecell" /> 
     </xsl:for-each> 

xsl:value-of命令出力XSLT 2.0でXSLT 1.0とは異なり、すべてのアイテム

はつまり

<xsl:value-of select="./namecell/@stuff"/> 

出力全てstuff属性(1及び2)次の命令

  <xsl:value-of select="./namecell" /> 

は2人のnamecell子供の文字列値を出力します - それぞれ"A"および"B"である。

ソリューション

置き換え

 <xsl:for-each select="./namerow"> 
      <xsl:value-of select="./namecell/@stuff"/> 
      <xsl:value-of select="./namecell" /> 
     </xsl:for-each> 

と:

 <xsl:for-each select="./namerow"> 
      <xsl:value-of select="./namecell/(@stuff|entity)"/> 
     </xsl:for-each> 

この修飾を有する完全なコードがです:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
     version="2.0"> 

    <xsl:output method="text"/> 

     <xsl:template match="/"> 
      <xsl:apply-templates select="Section/Chapter//nametable"/> 
     </xsl:template> 

     <xsl:template match="nametable"> 
      <xsl:for-each select="./namerow"> 
       <xsl:value-of select="./namecell/(@stuff|entity)"/> 
      </xsl:for-each> 
     </xsl:template> 

    <xsl:template match="text()"/> 
</xsl:stylesheet> 

と、この変換が提供されるXML文書に適用される場合:

<Section> 
    <Chapter> 
     <nametable> 
      <namerow> 
       <namecell stuff="1"> 
        <entity>A</entity> 
       </namecell> 
       <namecell stuff="2"> 
        <entity>B</entity> 
       </namecell> 
      </namerow> 
     </nametable> 
    </Chapter> 
</Section> 

指名手配結果が生成されます

1 A 2 B 

第二の溶液(おそらく何あなたが最初にやろうとしていた):

を交換してください:

<xsl:template match="nametable"> 
     <xsl:for-each select="./namerow"> 
      <xsl:value-of select="./namecell/@stuff"/> 
      <xsl:value-of select="./namecell" /> 
     </xsl:for-each> 
    </xsl:template> 

で:

<xsl:template match="nametable"> 
     <xsl:for-each select="namerow/namecell"> 
      <xsl:value-of select="@stuff"/> 
      <xsl:value-of select="entity"/> 
     </xsl:for-each> 
    </xsl:template> 

を今、あなたは再び指名手配結果を得る:

1A2B 
+0

oh!ここが答えです:) +1 –

+0

Dimitri:これは本当に何か? – JohnX

+0

@JohnX: 'は、各' stuff'属性の文字列値と 'namecellの' entity'子をテキストノードとして出力します'現在のノードの子ノードです。ここでは、Xpath * union *演算子 '|'を使用します。このような位置指定ステップでの結合は、XPath 2.0でのみ可能です(構文はXPath 1.0では違法です)。 –

1

私は、MSXMLを使用していますが、オペアンプとして1 Aを取得しています:|さてここで

は、それが宝石のように動作し、あなたのためのソリューションです:)

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="2.0"> 

    <xsl:output method="text"/> 

    <xsl:template match="/Section/Chapter/nametable/namerow/namecell"> 
    <xsl:value-of select="@stuff"/> 
    <xsl:text> </xsl:text><!--inserting a space--> 
    <xsl:value-of select="entity"/> 
    <xsl:text> </xsl:text><!--inserting a space--> 
    </xsl:template> 
    <xsl:template match="text()"/> 

</xsl:stylesheet> 
+0

私はcorreを得るために何をしたかということ私はSaxon EEを使用していますが、私の元の投稿がなぜそれほどうまくいかないのか分かりません。 – JohnX

+0

これは、 '/ @ stuff'の代わりに'/namecell/@ stuff'を使っているからかもしれません。私はxslt 2.0に本当に集中していません。 –

+0

Dimitreの答えを参照してください。 –

1

ご覧の挙動の理由は、あなたがnamerowを反復処理することです。 namecellを反復する場合は、<xsl:for-each select="namerow/namecell"><xsl:value-of select="@stuff"/><xsl:value-of select="." /></xsl:for-each>として1A2Bを取得します。 @stuffなどの各XPathでは、必ずしも1つの値(ノード)ではなく、値のセット(ノードセット)が得られます。その集合は一般に1つの値しか含まないが、だまされることはない。

同じことのもう一つの構文:<xsl:for-each select="namerow"><xsl:for-each select="namecell"><xsl:value-of select="@stuff"/><xsl:value-of select="." /></xsl:for-each></xsl:for-each>

P.S.ファイルシステムのパスと同じように、XPathの前に "./"を書く必要はありません。

+0

に基づいています)感謝! – JohnX

関連する問題