XQuery - 使用一个值来访问另一个

时间:2011-12-07 13:20:21

标签: xml xquery

我想从XML文档中提取所有知道英语的指南的名称,问题是我不知道怎么做。我使用XQuisitor查询XML文档。

段:

<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仅从指南节点打印指南的名称?

谢谢!

3 个答案:

答案 0 :(得分: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表达式并输出正确选择的节点

<gname>John Smith</gname>

答案 1 :(得分:2)

你甚至不需要使用XQuery,XPath也可以:

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

此查询会提取所有guideID等于其中一个guideID 的指南,这些指南已知英语并提取gname

确保了解XQuery的= - 运算符的集合语义!

答案 2 :(得分:2)

最直接的方式是这样的:

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

'let'语句是XPath 2.0 FLWOR语句的XQuery特定扩展,但保持代码可读非常方便。

有些人可能会争辩说你应该尽可能地限制使用//。但XQuery通常在XML数据库中运行,并且它们通常能够优化这些表达式。对于一个小任务,我不会担心性能虽然..