2014-01-16 2 views
1

Мне нужно придумать запрос, который дает продукты тех типов, из которых не было продано ни одного предмета. Значение, если предмет имеет тип одежды, и нет предметы одежды появятся в списке транзакций, мне нужно отобразить их.XPath Query: найдите элементы, которые имеют одинаковый список идентификаторов в качестве атрибутов

Это мой файл 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)

МОЕ НАПРЯЖЕНИЕ Я играл с некоторыми запросами, но я просто не могу понять. Это ближайший я получил:

Это то, что я пробовал:

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

Похоже, что это должно работать - найти все сделки, чьи продукты все соответствует атрибуту продукции других операций. Однако он не получает никаких хитов.

ответ

2

EDIT: По какой-то причине я думал, что это вопрос 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