2011-12-07 5 views
2

私はXML文書から英語を知っているすべてのガイドの名前を抽出したいと思っています。私はXML文書を照会するためにXQuisitorを使用します。XQuery - 別の値にアクセスするために1つの値を使用

スニペット:

<GuideLang> 
<guideID>1</guideID> 
<lname>English</lname> 
</GuideLang> 
<GuideLang> 
<guideID>2</guideID> 
<lname>German</lname> 
</GuideLang> 
<GuideLang> 
<guideID>3</guideID> 
<lname>Swedish</lname> 
</GuideLang> 
<Guide> 
<guideID>1</guideID> 
<gname>John Smith</gname> 
</Guide> 
<Guide> 
<guideID>2</guideID> 
<gname>Weber Schneider</gname> 
</Guide> 

私がいることを知っている:

element Result { 
//GuideLang[lname='English'] 
} 

が私に言語とガイドのIDに関するすべての情報を提供します - しかし、どのように私はIDが唯一のガイドの名前を印刷することを使用することができますガイドノードから?

ありがとうございます!

+0

"宿題"タグがありません? –

+0

これは私が読んでいる本の「割り当て」に過ぎず、この特定の質問に対する答えを知っていれば、残りの部分を見つけ出すことができます。 –

答えて

2

、XPathは、あまりにも、結構です:

//Guide[guideID=(//GuideLang[lname="English"]/guideID)]/gname 

このクエリは、そのguideIDguideIDの英語を話すことが知られており、そのgnameを抽出しているの1に等しいすべてのガイドをフェッチします。

XQueryの=オペレーターのセマンティクスについて知っておいてください!

let $english-guide-ids := //GuideLang[lname = 'English']/guideID 
return 
    //Guide[guideID = $english-guide-ids] 

の文は、XQuery固有のXPath 2.0 FLWOR文の拡張が、維持することは非常に便利である「みましょう」:

+0

私がやっている割り当てにはXQueryの使用が必要ですが、XQueryはXPathの拡張であることがわかります.XPathがそのような単純なタスクのXQueryと同義であるかどうか疑問に思っています。 –

+1

@ michael-kaesy Any有効なXPath式も有効ですXQuery .. – grtjn

+0

2言語を知っているガイドを取得する方法は?// Guide [guideID =(// GuideLang [lname = "英語"と "Swedish"]/guideID)]/gnameしかし、まったく同じ答えを返します。どのようなアイデアですか? –

4

を使用し、この純粋なXPath 2.0の式

/*/Guide 
    [for $gid in guideID 
    return ../GuideLang[guideID eq $gid and lname eq 'English'] 
    ] 
    /gname 

これは、提供文書フラグメントのノードは(設けない)XML文書の(設けない)頂部要素の子であることを想定。

これは、XPath 1.0式にでも変換することができます(何//が使用されていないことに注意!):

/*/Guide 
    [guideID 
    = 
    ../GuideLang[lname = 'English']/guideID 
    ] 
    /gname 

更新:ことを驚いている人々のためだけ

上記の最初の式は純粋なXPath 2.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"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/*"> 
    <xsl:sequence select= 
    "/*/Guide 
      [for $gid in guideID 
      return ../GuideLang[guideID eq $gid and lname eq 'English'] 
      ] 
      /gname 
    "/> 
</xsl:template> 
</xsl:stylesheet> 

このXSLT 2.0変換は、以下の文書(先頭の要素にラップ設け断片)に適用される場合:

<t> 
    <GuideLang> 
     <guideID>1</guideID> 
     <lname>English</lname> 
    </GuideLang> 
    <GuideLang> 
     <guideID>2</guideID> 
     <lname>German</lname> 
    </GuideLang> 
    <GuideLang> 
     <guideID>3</guideID> 
     <lname>Swedish</lname> 
    </GuideLang> 
    <Guide> 
     <guideID>1</guideID> 
     <gname>John Smith</gname> 
    </Guide> 
    <Guide> 
     <guideID>2</guideID> 
     <gname>Weber Schneider</gname> 
    </Guide> 
</t> 

XPath 2.0の式が評価され、正しく選択されたノードが出力されます:あなたもXQueryを使用する必要はありません

<gname>John Smith</gname> 
+0

純粋なXPathでflwor? –

+0

@Ranon:これはFLWRではありません。これは純粋なXPath 2.0です(これまでもありました)。正しい答えをdownvotingする前にXPath 2.0の知識を確認してください。 –

+0

すみません、あなたはまったく正しいです。私が疑問に思っていたので、XPath 2.0の文法をチェックしました。どのように私がコンテンツの中でさえも見落とすことができなかったか分からず、悲しいことに "for"のためにグレープすることは全く役に立たない。しかし、パフォーマンス上の理由から、私は述語と暗黙の結合に固執します。なぜなら、これらはより良い最適化を受ける傾向があるからです。 –

2

それを行うための最も直接的な方法は、このようなものになるだろうコードを読むことができます。

可能な限り//の使用を制限しようとする人もいます。しかし、XQueryはXMLデータベース内で動作することが多く、そのような表現を最適化できることがよくあります。小規模な課題のために、私は多くのパフォーマンスについて心配することはありません..

+0

編集:この方法でガイドの名前を返すだけでどうすればいいですか? –

+0

@ michael-kaesy上記のコードはgnameの代わりにGuide要素全体を返します。最後に/ gnameを追加して]これを修正してください。変数にenglish-guide-idsを入れると、RanonとDimitreのソリューションのように、* Guideの各要素を探すことができなくなります。 – grtjn