2011-12-22 9 views
3

ここに私の最初の投稿 - 確かに誰かが答えを知って欲しい! 私が持っていた多くの問題の解決策を見つけることができましたが、この解決策は見つかりませんでした。同じテーマに関する本サイト上の 質問と回答は、私の問題は解決しませんでした...XSLT 2.0 Xpathエラー「ノード項目ではありません」

私は

<Format> 
    <TagNr>92</TagNr> 
    <Option>A</Option> 
    <Format>//[N]15d</Format> 
</Format> 
<Format> 
    <TagNr>92</TagNr> 
    <Option>B</Option> 
    <Format>//3!a/3!a/15d</Format> 
</Format> 

ようなXML含むフォーマットの仕様を持つTagNr +オプションは、このノードセット内のユニークな組み合わせです。

私は簡単に形式のセットを使用して作成するキーを定義した:

<xsl:key name="xx" match="//Format/Format" use="concat(../TagNr, ../Option)"/> 

私は確かにだけ非特殊な要素で、このキーを使用して正しい値を得ることができます。以下のようなfor-eachまたは他の構文の中でこのキーを使用すると、「XPath 2.0の式でエラーが発生しました。ノード項目ではありません」というエラーが表示されます。

私が達成しようとするのは次のとおりです。処理される他のノードには、各文字の書式を取得するオプションの文字列があります。用(のみ)の値を取得する際に正規表現を使用して、個々の文字に

<xsl:variable name="TN"><xsl:value-of select="TagNr"/></xsl:variable> 
<xsl:variable name="optList"> 
    <xsl:analyze-string select="./Options" regex="[A-Z]"> 
     <xsl:matching-substring> 
      <xsl:variable name="TNO" select="concat($TN, .)"/> 
      <opt> 
       <tag><xsl:value-of select="$TNO"/></tag> 
       <fmt><xsl:value-of select="key('xx', $TNO)"/></fmt> 
      </opt> 
     </xsl:matching-substring> 
    </xsl:analyze-string> 
</xsl:variable> 

分割が細かい行くと:

<Tag> 
    <TagNr>92</TagNr> 
    <Options>AB</Options> 
</Tag> 

私は以下の亜種の多くが、運をしようとしている。例えば opt/tagもうまくいきます。 しかし、opt/fmtを追加すると、前述のXpath式のエラーメッセージが表示されますselect = "key( 'xx'、$ TNO)"

このサイトの別のスレッドで提案されているように、キー機能に基づいて変数を定義しようとしましたが、成功しませんでした。

誰でも手伝ってもらえますか?

答えて

5

key()関数は、コンテキストノードを含むドキュメントを検索します。コンテキスト項目がノードでない場合(たとえば、analyze-string内)、検索する文書がわからないためこのエラーが発生します。答えはkey()の3番目の引数を使用してこの情報を提供することです。

+0

スーパーの皆さん、本当に感謝しています。私は、キー関数の第3引数を正確にどのように指定するのだろうか?それはドキュメントルートを示す "/"のようなものでしょうか?私はこれに関する情報をXSLT 2.0のガイドで見つけることができません。 – Maestro13

1

問題は、analyze-string要素のコンテキストが変更されることです。次の解決策が役立つかもしれません。そのようなXMLファイルの場合

<a> 
    <Format> 
     <TagNr>92</TagNr> 
     <Option>A</Option> 
     <Format>//[N]15d</Format> 
    </Format> 
    <Format> 
     <TagNr>92</TagNr> 
     <Option>B</Option> 
     <Format>//3!a/3!a/15d</Format> 
    </Format> 
    <Tag> 
     <TagNr>92</TagNr> 
     <Options>AB</Options> 
    </Tag> 
</a> 

には、次のXSLTを考えてみましょう:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0"> 
    <xsl:output indent="yes"/> 
    <xsl:key name="xx" match="//Format/Format" use="concat(../TagNr, ../Option)"/> 
    <xsl:template match="/"> 
     <result> 
      <xsl:apply-templates select="//Tag"/>    
     </result> 
    </xsl:template> 
    <xsl:template match="Tag"> 
     <xsl:call-template name="createOPT"> 
      <xsl:with-param name="str" as="xs:string" select="Options"/> 
     </xsl:call-template>     
    </xsl:template> 
    <xsl:template name="createOPT"> 
     <xsl:param name="str"/> 
     <xsl:if test="string-length($str) > 0"> 
      <xsl:variable name="firstChar" select="substring($str,1,1)"/> 
      <xsl:variable name="TNO" select="concat(TagNr,$firstChar)"/> 
      <opt> 
       <tag><xsl:value-of select="$TNO"/></tag> 
       <fmt><xsl:value-of select="key('xx', $TNO)"/></fmt> 
      </opt> 
      <xsl:call-template name="createOPT"> 
       <xsl:with-param name="str" select="substring($str,2)"/> 
      </xsl:call-template> 
     </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

結果は次のとおりです。

<?xml version="1.0" encoding="UTF-8"?> 
<result> 
    <opt> 
     <tag>92A</tag> 
     <fmt>//[N]15d</fmt> 
    </opt> 
    <opt> 
     <tag>92B</tag> 
     <fmt>//3!a/3!a/15d</fmt> 
    </opt> 
</result> 
+0

ありがとう - これは間違いなく私に再び行く!また、私が最初にやりたかったcharの部分文字列の手段を私に提供します。しかし、1つの質問:コンテキストは失われますが、なぜですか?そして、なぜこのサイトの別のスレッドで述べたように、洗練された解決策がないのですか?変数を定義してコンテキストを取り戻すのはなぜですか? – Maestro13

+0

変数を操作してコンテキストを取り戻すこともできます。多分それはよりエレガントです。私の謙虚な個人的な見方は、 'analyze-string'は使い方や維持に少し不自由なので、可能ならば避けることを好みます。 –

+1

コンテキストは失われませんが、analyze-stringの内部ではノードではなく、現在処理中のアトミックアイテム、つまり(サブ)ストリングです。 –

1

処理するための最も簡単なXSLT 2.0の方法文字列ごとの文字列は、次のとおりです。

あなたは変数に原稿コンテキストを保存する($vDoc言う)とkey()関数の第三引数として、この変数を使用して、これを組み合わせることができます - のみの機能 - 再びXSLT 2.0です。

key('xx', concat($TN, $vChar), $vDoc) 

概要:文字ごとの文字処理のためstring-to-codepoints()codepoints-to-string()機能

  1. 使用

    だから、あなたのようなものがあるでしょう。

  2. key()の3番目の引数を使用して、現在と異なるコンテキストを指定します。

+0

これは、「元のドキュメントのコンテキストを変数に保存する」ということがどれくらい正確に行われているのでしょうか? – Maestro13

+0

@ Maestro13:このように: ''この変数の定義はグローバル( 'xsl:stylesheet'の子)にすることができます –

+0

@ Maestro13:それはあなたのコメントに便利です)?それでも問題はありますか? –

関連する問題