2014-01-16 140 views
1

我需要提供一个查询,该查询可以提供没有任何项目的类型的产品如果某个项目是服装类型,并且没有服装项目出现在交易清单中,我需要显示它。XPath查询:查找具有与属性相同的ID列表的元素

这是我的XML文件(超级加拿大岬道歉):

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE store [ 

<!ELEMENT store (product*, transaction*)> 
<!ATTLIST store name CDATA #REQUIRED > 

<!ELEMENT product EMPTY> 
    <!ATTLIST product 
     name ID #REQUIRED 
     type CDATA #REQUIRED 
     price CDATA #REQUIRED 
    > 

    <!ELEMENT transaction EMPTY> 
    <!ATTLIST transaction 
products IDREFS #REQUIRED 
sumPrice CDATA #REQUIRED 
    > 

]> 
<store name="Gordons"> 
<product name="beaverCoat" type="clothing" price="100"/> 
<product name="hockeyStick" type="equipment" price="30"/> 
<product name="hockeyPuck" type="equipment" price="5"/> 
<product name="icePick" type="equipment" price="40"/> 
<product name="mooseMeat" type="food" price="350"/> 
<product name="salmon" type="food" price="15"/> 
<transaction products="salmon mooseMeat" sumPrice="365"/>  
<transaction products="hockeyPuck hockeyStick" sumPrice="35"/> 
<transaction products="hockeyStick mooseMeat" sumPrice="380"/> 
<transaction products="salmon mooseMeat" sumPrice="300"/> 
<transaction products="hockeyStick hockeyStick hockeyStick" sumPrice="30"/> 
</store> 

所需的输出

<transaction products="salmon mooseMeat" sumPrice="365"/> 
<transaction products="salmon mooseMeat" sumPrice="300"/> 

,因为他们具有相同的产品作为另一交易交易(eachother)

MY ATTEMPT 我玩过一些查询,但我无法正确理解。这是我已经得到最接近:

这是我已经试过:

//transaction[id(@products) = //transaction/@products] 

看起来这应该工作 - 发现其产品符合所有其他交易产品属性的所有事务。然而,它没有获得任何奖项。

回答

2

编辑:出于某种原因,我认为这是一个XSLT问题。这里是你可以只用XPath的做到这一点的一种方法:

//transaction[(@products = preceding-sibling::transaction/@products or 
       @products = following-sibling::transaction/@products)] 

这里是你如何可以查询所有这些不同的元素(需要的XPath 2.0):

//transaction[(@products = preceding-sibling::transaction/@products or 
       @products = following-sibling::transaction/@products) and 
       not(concat(@products, '+', @sumPrice) = 
        preceding-sibling::transaction/concat(@products, '+', @sumPrice))] 

这里有一种方法用XSLT来做到这一点:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> 
    <xsl:key name="kTrans" match="transaction" use="@products" /> 

    <xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="/*"> 
    <n> 
     <xsl:apply-templates select="transaction[key('kTrans', @products)[2]]" /> 
    </n> 
    </xsl:template> 
</xsl:stylesheet> 

当你的样品输入运行,其结果是:

<n> 
    <transaction products="salmon mooseMeat" sumPrice="365" /> 
    <transaction products="salmon mooseMeat" sumPrice="300" /> 
</n> 

请注意,我将结果封装在n元素中,因为使用多个根元素的XML无效。

+0

它的工作原理!谢谢!但是,有没有办法只返回不同的元素?当'sumPrice'是相同的,它不应该同时打印。 – CodyBugstein

+0

你知道你的XPath引擎是否可以使用XPath 2.0吗?我可以想办法在XPath 2.0中排除重复项,但不是在1.0中。 – JLRishe

+0

nope它不能:( – CodyBugstein

相关问题