2011-08-26 145 views
1
<parents> 
<parent> 
    <item> 
     <name>200</name> 
    </item> 
    <item> 
     <name>201</name> 
    </item> 
    <item> 
     <name>204</name> 
    </item> 
</parent> 
<parent> 
    <item> 
     <name>203</name> 
    </item> 
</parent> 
</parents> 

我需要第一个parent节点,因为我有一个与项目对应的ID列表。试想一下:如何根据多个子节点值获取父节点?

list = ['200', '201']; 

因为200在第一parent节点被发现,我想要那个parent节点。如果200不存在,我仍然会得到父节点,因为201是位于第一个parent中的/name/text()的值。

我的唯一要求是我需要抓住parent节点,如果发现我的list中的ID为one

目前我只测试为先,就像这样:

//name/child::text()[.="' . $firstKey . '"]/../../../../

$firstKey是在列表中,200的第一个元素的引用。这并不理想,因为它不检查所有值,但只检查第一个值。

+0

好问题,+1。查看我对两种解决方案的回答 - 一个XPath 1.0 + XSLT解决方案和一个XPath 2.0解决方案 –

回答

1

I. XPath 1.0中使用XSLT 1溶液。0作为主机

用途:

/*/parent[item/name = $vList] 

这种转变

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:my="my:my"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<my:list> 
    <val>200</val> 
    <val>201</val> 
</my:list> 

<xsl:variable name="vList" select= 
    "document('')/*/my:list/*"/> 

<xsl:template match="/"> 
    <xsl:copy-of select="*/parent[item/name = $vList]"/> 
</xsl:template> 
</xsl:stylesheet> 

时所提供的XML文档应用:

<parents> 
    <parent> 
     <item> 
      <name>200</name> 
     </item> 
     <item> 
      <name>201</name> 
     </item> 
     <item> 
      <name>204</name> 
     </item> 
    </parent> 
    <parent> 
     <item> 
      <name>203</name> 
     </item> 
    </parent> 
</parents> 

产生想要的,正确的结果

<parent> 
    <item> 
     <name>200</name> 
    </item> 
    <item> 
     <name>201</name> 
    </item> 
    <item> 
     <name>204</name> 
    </item> 
</parent> 

注意:您可以通过现在<my:list>什么作为参数的转变。

二,使用XPath 2.0

/*/parent[item/name = ('200', '201')] 

的XSLT 2.0 - 基于验证低于”

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:my="my:my"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="/"> 
    <xsl:copy-of select="*/parent[item/name = ('200', '201')]"/> 
</xsl:template> 
</xsl:stylesheet> 

当这个变换所提供的XML文档(上文)施加相同的正确的结果被产生。

+0

看起来像'('200','201')在逗号当使用这个不是在XSLT的上下文中,而是在各种语言中的XPATH接口?这是否意味着他们没有使用xpath 2.0,还是仅在XSLT环境中有效? –

+0

@meder:这是标准的XPath 2.0 - 任何XPath 2.0引擎都支持这一点。例如,这在XQuery中是有效的,因为XQuery是XPath 2.0的超集。因此,要回答这个问题,如果给定的XPath引擎无法评估此表达式(并且很可能引发语法错误),这意味着它不支持XPath 2.0。 –

+0

是啊,呃... –

0

像这样的东西可能会有所帮助:

//parent[.//item[name[text()='200' or text()='201']]] 

你必须构建最里面的谓词(与text()='200' or ...)编程,虽然。我不确定你使用的是哪种上下文,但是由于你使用了一个变量引用,所以我假设了XSLT。我会看看有没有什么更适合...

编辑:我能想到的唯一的事情是连接所有你的钥匙一些符号,你是相信他们会不会包含作为分隔符。例如:

200#201#... 

然后使用XPath contains功能:

//parent[.//item[name[contains('200#201#...', normalize-space(text()))]]] 

的则包含必须是你的级联键,或许传过来的变量的第一个参数。函数string-join对此很有用,但我相信它仅在XPath 2.0中可用。

0

如果你有XSLT 2.0,你可以说

<xsl:variable name="list" select="(200, 201)" /> 
<xsl:variable name="theParent" select="(//parent[item/name = $list])[1]" /> 

=作品的存在主义比较,返回true,如果在左侧的节点集的任何产品上的序列中等于任何项目=的右侧。

(未测试)

相关问题