【问题标题】:XPath Query: Find elements that have the same list of IDs as attributesXPath 查询:查找与属性具有相同 ID 列表的元素
【发布时间】:2014-01-16 07:13:10
【问题描述】:

我需要提出一个查询,给出没有售出商品的类型的产品 意思是如果一个商品属于服装类型,并且没有服装商品出现在交易列表中,我需要显示它.

这是我的 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"/>

因为它们是与另一个交易(彼此)具有相同产品的交易

我的尝试 我玩过一些查询,但我就是做错了。这是我得到的最接近的:

这是我尝试过的:

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

这似乎应该可行 - 查找其产品都与其他交易的产品属性匹配的所有交易。但是它没有得到任何点击。

【问题讨论】:

    标签: xml xpath xpathquery


    【解决方案1】:

    编辑:出于某种原因,我认为这是一个 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 是无效的。

    【讨论】:

    • 有效!谢谢!但是,有没有办法只返回不同的元素?当sumPrice 相同时,不应同时打印两者。
    • 您知道您的 XPath 引擎是否可以使用 XPath 2.0?我可以想办法在 XPath 2.0 中排除重复项,但在 1.0 中没有。
    • 你能看看我问过的类似问题吗:stackoverflow.com/questions/21150895/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-09
    • 2013-07-03
    • 1970-01-01
    • 1970-01-01
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多