2017-09-22 9 views
0

xpathを動的に作成してxmlノードの属性の値を取得しようとしています。しかし、常に空の値を返しています。私がxpathをハードコードすると、うまく動作します。以下のサンプルXMLファイルです:入力から目的のIDを読み取るxpathを使用してノードを取得できません

<root> 
<PR id="id6016" name="OUTER WORLD"> 
    <ADS id="id6017" dsRef="#id15" role="form1"> 
    </ADS> 
    <ADS id="id6018" dsRef="#id9" role="form1"> 
    </ADS> 
</PR> 

<PR id="id1000" name="OUTER WORLD"> 
    <ADS id="id1001" dsRef="#id16" role="form1"> 
    </ADS> 
    <ADS id="id1002" dsRef="#id10" role="form1"> 
    </ADS> 
</PR> 

<DS id="id9" name="form1" version="7" type="CAD"> 
</DS> 

<DS id="id15" name="form1" version="1" type="MSWord"> 
</DS> 

<DS id="id10" name="form1" version="1" type="CAD"> 
</DS> 

<DS id="id16" name="form1" version="1" type="MSWord"> 
</DS> 

</root> 

マイサンプルXSLは次のとおりです。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" omit-xml-declaration="no" indent="no" encoding="utf-8"/> 
    <xsl:template match="/root"> 
    <result> 
     <xsl:apply-templates select="PR" mode="PR" /> 
    </result> 
    </xsl:template> 

    <xsl:template match="PR" mode="PR"> 
    <PR> 
     <xsl:attribute name="id"> 
     <xsl:value-of select="@id" /> 
     </xsl:attribute> 
     <xsl:attribute name="name"> 
     <xsl:value-of select="@name" /> 
     </xsl:attribute> 
     <xsl:for-each select="ADS[@role='form1']"> 
     <DS> 
      <xsl:attribute name="id"> 
      <xsl:value-of select="string(substring-after(@dsRef, '#'))" /> 
      </xsl:attribute> 
      <xsl:value-of select="../DS[@id=string(substring-after(@dsRef, '#'))]/@type" /> 
     </DS>   

     </xsl:for-each> 
     <DS2> 
     <xsl:value-of select="../DS[@id='id9']/@type" /> 
     </DS2>  
     <DS3> 
     <xsl:value-of select="../DS[@id=string(substring-after(@dsRef, '#'))]/@type" /> 
     </DS3> 

    </PR> 
    </xsl:template> 
</xsl:stylesheet> 

あなたは私がDS2タグのためではなく、DSやDS3のための任意のInnerTextプロパティを取得見ることができるように。私はまた、私が得ているIDが良いことを示すために、DSタグにid属性を追加しました。

最終的には、type = "CAD"のIDタグをフィルタして変数に格納する必要がありますが、今はxpathを使用してXMLノードを取得できないため、スタックされています。私が正しくあなたの問題のあなたの説明を理解している場合は

答えて

0

、DS2要素で

<xsl:value-of select="../DS[@id='id9']/@type" /> 

命令は期待と希望する値を生成しているが、命令DS3要素で

<xsl:value-of select="../DS[@id=string(substring-after(@dsRef, '#'))]/@type" /> 

そうではありません。同様に、xsl:for-each内で生成されているDS要素の@id属性には期待値が格納されていますが、要素の内容は期待どおりではありません。 (プロのヒント:あなたが期待していたものと異なるものをどうやって理解しているか分からない場合は、Stack Overflowに関する質問への回答が得られます)

ここでは2つの問題があります。

最初に、@dsRefの参照は、その属性参照のコンテキスト要素がdsRef要素を持つADS要素であるため、xsl:for-eachの最初のxsl:value-ofで成功します。 xsl:for-eachの2番目のxsl:value-ofの@dsRefへの参照は、述語の内部にあるため失敗し、context要素は述語がテストされているDS要素です。 DS3デバッグ要素の@dsRefへの参照は、同様に、DS要素の存在しない「dsRef」属性への参照です。

この問題を解決する方法は2つあります。 current()を読むことができます。とりわけ、述語内からXPath式全体のコンテキスト要素を指し示し、属性参照をcurrent()/@dsRefのように書き換える方法があります。多くの人がこの道をお勧めします。

current()について学ぶ必要がなく、特定のポイントで登るコンテキストノードのスタックを正確に何ステップアップして、あなたの表現で参照できる変数にバインドすることができます。 (私はXSLTプログラムを書く年間を過ごすことが可能であるとcurrent()のすべての厄介な詳細を理解する必要がないことを経験から知っている。)あなたのために、それぞれ次のようになり、この場合になります

<xsl:for-each select="ADS[@role='form1']"> 
    <xsl:variable name="targetDS" select="substring-after(@dsRef,'#')"/> 
    <DS> 
    <xsl:attribute name="id"> 
     <xsl:value-of select="$targetDS" /> 
    </xsl:attribute> 
    <xsl:value-of select="../DS[@id=$targetDS]/@type" /> 
    </DS>   
</xsl:for-each> 

あなたがかもしれません名前付き変数にターゲットIDを持たせると、2つの値の指示が何をしているのかが分かりやすくなります。

この変更後、プログラムはまだ動作しません。

あなたの第二の問題は、現在のADSの要素の兄弟の間でDSの要素を探しているということですが、あなたの入力にはADS要素は、実際にはDSの兄弟を持っていません。彼らはすべてPRの兄弟です。 「ID」は、あなたの要素の属性場合はXML IDとして振る舞う、その要素の階層的な場所は軽微であり、かつ

//DS[@id=$targetDS] 

のような単純な式は、より弾力的(かつ明確)になります。あなたはDTDを持っており、「ID」属性が型IDを持つものとして宣言されている場合、そのIDである$ targetDS要素」を意味している

id($targetDS) 

を書くことさえも簡単です。なんらかの理由で実際に入力文書の特定の領域のDS要素に式を制限したい場合は、その領域を正しく参照する必要があります。 ..../..に置き換えた後、スタイルシートは私が予想した結果であると信じていました。

+0

あなたの説明に感謝します。私は現在の()関数を使用していないが、私はより頻繁に私のコードでそれを使用して調べます。上記で共有したxmlはスニペットに過ぎません。残念ながら元のxmlにはIDを定義するDTDが含まれていません。私はxpathでid9をハードコードするときにtype属性の値を取得しますが、変数を使用するときは取得しません。 – DS1

+0

2つのデバッグ要素DS2とDS3はfor-eachの外側にあります。コンテキストノードはADSではなくPRです。それぞれをfor-eachに移動すると、コンテキストノードがADS要素なので、両方が失敗することがわかります。 –

関連する問題