XQuery/XPath:如何获取与另一个元素值相比具有较低元素值的元素
XQuery/XPath: How to get element with a lower element value compared to another element value
我会举个例子来更好地解释我自己:
<company>
<products>
<product ean="111">
<listingPrice>100</listingPrice>
</product>
<product ean="222">
<listingPrice>500</listPrice>
</product>
<product ean="333">
<listingPrice>1000</listingPrice>
</product>
</products>
<shops>
<shop id="1">
<product>
<ean>111</ean>
<sellingPrice>90</sellingPrice>
</product>
</shop>
<shop id="2">
<product>
<ean>888</ean>
<sellingPrice>10</sellingPrice>
</product>
<product>
<ean>222</ean>
<sellingPrice>300</sellingPrice>
</product>
</shop>
<shop id="3">
<product>
<ean>222</ean>
<sellingPrice>600</sellingPrice>
</product>
</shop>
<shop id="4">
<product>
<ean>111</ean>
<sellingPrice>20</sellingPrice>
</product>
<product>
<ean>333</ean>
<sellingPrice>140</sellingPrice>
</product>
</shop>
</shops>
</company>
我想显示售价值比标价至少低 20% 的所有产品,并且必须是相同的产品才能比较价格。最后会显示商店 ID 及其产品 ean、售价和标价。
示例解决方案将是:
<shop id="2">
<product ean="222" sellingPrice="300" listingPrice="500"/>
</shop>
<shop id="4">
<product ean="111" sellingPrice="20" listingPrice="100"/>
<product ean="333" sellingPrice="140" listingPrice="1000"/>
</shop>
到目前为止我得到了什么:
let $a := fn:doc('shop.xml'),
$b := $a//products/* ,
$c:= $a//shops/*
return
for $x in $c
let $z:=
if ($x/product/ean = $b/@ean and $x/product/sellingPrice < $b/(listingPrice *0.8 ) )
then
<shop id="{$x/@*}">
<product ean="{$x/product/ean}" sellingPrice="{$x/product/sellingPrice}" listingPrice="{$b/listingPrice}"/>
</shop>
return $z
我错过了什么?
我认为它有助于提取引用和比较以在函数中重用,我也喜欢使用 !
映射运算符来使表达式更紧凑:
declare variable $factor as xs:decimal external := 0.8;
declare function local:listing-price($product as element(product)) as xs:decimal?
{
root($product)/company/products/product[@ean = $product/ean]/listingPrice
};
declare function local:check-price($product as element(product), $factor as xs:decimal) as xs:boolean
{
$product/sellingPrice < local:listing-price($product) * $factor
};
/company/shops/shop[product[local:check-price(., $factor)]]
!
<shop id="{@id}">{
product[local:check-price(., $factor)]
!
<product ean="{ean}" sellingPrice="{sellingPrice}" listingPrice="{local:listing-price(.)}" />
}</shop>
https://xqueryfiddle.liberty-development.net/nc4P6y7
要从文件加载,您可以在路径前加上 doc()
调用:
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method 'xml';
declare option output:indent 'yes';
declare variable $factor as xs:decimal external := 0.8;
declare function local:listing-price($product as element(product)) as xs:decimal?
{
root($product)/company/products/product[@ean = $product/ean]/listingPrice
};
declare function local:check-price($product as element(product), $factor as xs:decimal) as xs:boolean
{
$product/sellingPrice < local:listing-price($product) * $factor
};
doc('https://github.com/martin-honnen/martin-honnen.github.io/raw/master/xslt/2020/test2020051601.xml')/company/shops/shop[product[local:check-price(., $factor)]]
!
<shop id="{@id}">{
product[local:check-price(., $factor)]
!
<product ean="{ean}" sellingPrice="{sellingPrice}" listingPrice="{local:listing-price(.)}" />
}</shop>
https://xqueryfiddle.liberty-development.net/nc4P6y7/1 or with declare context item at https://xqueryfiddle.liberty-development.net/nc4P6y7/2.
我会举个例子来更好地解释我自己:
<company>
<products>
<product ean="111">
<listingPrice>100</listingPrice>
</product>
<product ean="222">
<listingPrice>500</listPrice>
</product>
<product ean="333">
<listingPrice>1000</listingPrice>
</product>
</products>
<shops>
<shop id="1">
<product>
<ean>111</ean>
<sellingPrice>90</sellingPrice>
</product>
</shop>
<shop id="2">
<product>
<ean>888</ean>
<sellingPrice>10</sellingPrice>
</product>
<product>
<ean>222</ean>
<sellingPrice>300</sellingPrice>
</product>
</shop>
<shop id="3">
<product>
<ean>222</ean>
<sellingPrice>600</sellingPrice>
</product>
</shop>
<shop id="4">
<product>
<ean>111</ean>
<sellingPrice>20</sellingPrice>
</product>
<product>
<ean>333</ean>
<sellingPrice>140</sellingPrice>
</product>
</shop>
</shops>
</company>
我想显示售价值比标价至少低 20% 的所有产品,并且必须是相同的产品才能比较价格。最后会显示商店 ID 及其产品 ean、售价和标价。
示例解决方案将是:
<shop id="2">
<product ean="222" sellingPrice="300" listingPrice="500"/>
</shop>
<shop id="4">
<product ean="111" sellingPrice="20" listingPrice="100"/>
<product ean="333" sellingPrice="140" listingPrice="1000"/>
</shop>
到目前为止我得到了什么:
let $a := fn:doc('shop.xml'),
$b := $a//products/* ,
$c:= $a//shops/*
return
for $x in $c
let $z:=
if ($x/product/ean = $b/@ean and $x/product/sellingPrice < $b/(listingPrice *0.8 ) )
then
<shop id="{$x/@*}">
<product ean="{$x/product/ean}" sellingPrice="{$x/product/sellingPrice}" listingPrice="{$b/listingPrice}"/>
</shop>
return $z
我错过了什么?
我认为它有助于提取引用和比较以在函数中重用,我也喜欢使用 !
映射运算符来使表达式更紧凑:
declare variable $factor as xs:decimal external := 0.8;
declare function local:listing-price($product as element(product)) as xs:decimal?
{
root($product)/company/products/product[@ean = $product/ean]/listingPrice
};
declare function local:check-price($product as element(product), $factor as xs:decimal) as xs:boolean
{
$product/sellingPrice < local:listing-price($product) * $factor
};
/company/shops/shop[product[local:check-price(., $factor)]]
!
<shop id="{@id}">{
product[local:check-price(., $factor)]
!
<product ean="{ean}" sellingPrice="{sellingPrice}" listingPrice="{local:listing-price(.)}" />
}</shop>
https://xqueryfiddle.liberty-development.net/nc4P6y7
要从文件加载,您可以在路径前加上 doc()
调用:
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method 'xml';
declare option output:indent 'yes';
declare variable $factor as xs:decimal external := 0.8;
declare function local:listing-price($product as element(product)) as xs:decimal?
{
root($product)/company/products/product[@ean = $product/ean]/listingPrice
};
declare function local:check-price($product as element(product), $factor as xs:decimal) as xs:boolean
{
$product/sellingPrice < local:listing-price($product) * $factor
};
doc('https://github.com/martin-honnen/martin-honnen.github.io/raw/master/xslt/2020/test2020051601.xml')/company/shops/shop[product[local:check-price(., $factor)]]
!
<shop id="{@id}">{
product[local:check-price(., $factor)]
!
<product ean="{ean}" sellingPrice="{sellingPrice}" listingPrice="{local:listing-price(.)}" />
}</shop>
https://xqueryfiddle.liberty-development.net/nc4P6y7/1 or with declare context item at https://xqueryfiddle.liberty-development.net/nc4P6y7/2.