对结果进行分组的 XQuery 语句

发布于 2024-09-25 17:15:01 字数 2157 浏览 2 评论 0原文

我有一个 XML 结构,需要使用 XQuery 进行查询。 据我所知,这甚至可能是不可能的,但由于我对 XQuery 很陌生,我想我可能会问。

我需要查询下面的 XML 并返回如下所示的内容:

<product>
 <title>Acer Liquid</title>
 <image>ACER-LIQUID.jpg</image>
 <networks>
  <network>O2O</network>
  <network>VOD</network>
 </networks>
 <colours>
  <colour>Blue</colour>
  <colour>Black</colour>
 </colours>
</product>

所以我的查询本质上是这样的: 获取所有产品详细信息,其中存在属于指向它的“每月付款”的销售包(通过 main_product),并附加指向它的每个销售包的网络属性。但按product.product_model 字段对结果进行分组。

源 XML:

<root>
 <package>
  <title>package1</title>
  <categories><category group="Other" name="Pay Monthly"/></categories>
  <properties>
    <value key="main_product">PRODUCT#14649766#PART#ACERLIQUIDBLACK</value>
    <value key="network_code">O2O</value>
  </properties>
 </package>
 <package>
  <title>package2</title>
  <categories><category group="Other" name="Pay Monthly"/></categories>
  <properties>
    <value key="main_product">PRODUCT#14649700#PART#ACERLIQUIDBLUE</value>
    <value key="network_code">VOD</value>
  </properties>
 </package>
 <product>
  <title>Acer Liquid</title>
  <properties>
   <value key="product_code">PRODUCT#14649700#PART#ACERLIQUIDBLUE</value>
   <value key="product_model">Acer Liquid|ACER_LIQUID</value>
   <value key="product_image_url">ACER-LIQUID.jpg</value>
   <value key="colour">Blue</value>
  </properties>
 </product>
 <product>
  <title>Acer Liquid</title>
  <properties>
   <value key="product_code">PRODUCT#14649766#PART#ACERLIQUIDBLACK</value>
   <value key="product_model">Acer Liquid|ACER_LIQUID</value>
   <value key="product_image_url">ACER-LIQUID.jpg</value>
   <value key="colour">Black</value>
  </properties>
 </product>
</root>

I have an XML structure that I need to query using XQuery.
As far as I have been able to find, this may not even be possible, but since I am so new to XQuery I thought I may ask.

I need to query the XML below and return something that looks like:

<product>
 <title>Acer Liquid</title>
 <image>ACER-LIQUID.jpg</image>
 <networks>
  <network>O2O</network>
  <network>VOD</network>
 </networks>
 <colours>
  <colour>Blue</colour>
  <colour>Black</colour>
 </colours>
</product>

So my query is essentially something like:
Get all product details where there is a salespackage that belongs to "Pay Monthly" that points to it (via main_product), and attach the network property from each sales package that points to it. But group the results by the product.product_model field.

Source XML:

<root>
 <package>
  <title>package1</title>
  <categories><category group="Other" name="Pay Monthly"/></categories>
  <properties>
    <value key="main_product">PRODUCT#14649766#PART#ACERLIQUIDBLACK</value>
    <value key="network_code">O2O</value>
  </properties>
 </package>
 <package>
  <title>package2</title>
  <categories><category group="Other" name="Pay Monthly"/></categories>
  <properties>
    <value key="main_product">PRODUCT#14649700#PART#ACERLIQUIDBLUE</value>
    <value key="network_code">VOD</value>
  </properties>
 </package>
 <product>
  <title>Acer Liquid</title>
  <properties>
   <value key="product_code">PRODUCT#14649700#PART#ACERLIQUIDBLUE</value>
   <value key="product_model">Acer Liquid|ACER_LIQUID</value>
   <value key="product_image_url">ACER-LIQUID.jpg</value>
   <value key="colour">Blue</value>
  </properties>
 </product>
 <product>
  <title>Acer Liquid</title>
  <properties>
   <value key="product_code">PRODUCT#14649766#PART#ACERLIQUIDBLACK</value>
   <value key="product_model">Acer Liquid|ACER_LIQUID</value>
   <value key="product_image_url">ACER-LIQUID.jpg</value>
   <value key="colour">Black</value>
  </properties>
 </product>
</root>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

自我难过 2024-10-02 17:15:01

XQuery 1.0 相当复杂的查询:

declare ordering unordered;

declare function local:values($items as node()*,
                              $property as xs:string) as xs:string* {
    distinct-values($items/properties/value[@key eq $property])
};

declare function local:filter($items as node()*, 
                              $property as xs:string,
                              $values as xs:string*) as node()* {
    $items[properties/value[@key eq $property] = $values]
};


let $packages := doc('source')/root/package[categories/category[@name eq 'Pay Monthly']]
let $products := local:filter(doc('source')/root/product, 
                              'product_code',
                              local:values($packages, 'main_product'))

for $model           in local:values($products, 'product_model')
let $model_products  := local:filter($products, 'product_model', $model)
let $model_packages  := local:filter($packages,
                                     'main_product',
                                     local:values($model_products, 'product_code'))

return
<product>
    {$model_products[1]/title}
    <image>{local:values($model_products[1], 'product_image_url')}</image>
    <networks>{
        for $net in local:values($model_packages, 'network_code')
        return <network>{$net}</network>
    }</networks>
    <colours>{
        for $cl in local:values($model_products, 'colour')
        return <colour>{$cl}</colour>
    }</colours>
</product>

Quite complex query for XQuery 1.0:

declare ordering unordered;

declare function local:values($items as node()*,
                              $property as xs:string) as xs:string* {
    distinct-values($items/properties/value[@key eq $property])
};

declare function local:filter($items as node()*, 
                              $property as xs:string,
                              $values as xs:string*) as node()* {
    $items[properties/value[@key eq $property] = $values]
};


let $packages := doc('source')/root/package[categories/category[@name eq 'Pay Monthly']]
let $products := local:filter(doc('source')/root/product, 
                              'product_code',
                              local:values($packages, 'main_product'))

for $model           in local:values($products, 'product_model')
let $model_products  := local:filter($products, 'product_model', $model)
let $model_packages  := local:filter($packages,
                                     'main_product',
                                     local:values($model_products, 'product_code'))

return
<product>
    {$model_products[1]/title}
    <image>{local:values($model_products[1], 'product_image_url')}</image>
    <networks>{
        for $net in local:values($model_packages, 'network_code')
        return <network>{$net}</network>
    }</networks>
    <colours>{
        for $cl in local:values($model_products, 'colour')
        return <colour>{$cl}</colour>
    }</colours>
</product>
予囚 2024-10-02 17:15:01

此 XQuery:

for $title in (/root/product/title)[index-of(/root/product/title,.)[1]]
let $ProductsProp := /root/product[title=$title]/properties/value
return 
<product>
    {$title}
    <image>{string(($ProductsProp[@key='product_image_url'])[1])}</image>
    <networks>{
        for $network in /root/package/properties
                                  [value[@key='main_product']
                                   = $ProductsProp[@key='product_code']]
                                  /value[@key='network_code']/string()
        return
        <network>{$network}</network>
    }</networks>
    <colours>{
        for $colour in $ProductsProp[@key='colour']/string()
        return
        <colour>{$colour}</colour>
    }</colours>
</product>

输出:

<product>
    <title>Acer Liquid</title>
    <image>ACER-LIQUID.jpg</image>
    <networks>
        <network>O2O</network>
        <network>VOD</network>
    </networks>
    <colours>
        <colour>Blue</colour>
        <colour>Black</colour>
    </colours>
</product>

注意:XPath 2.0 分组表达式 $vSeq[index-of($vSeq,.)[1]]

This XQuery:

for $title in (/root/product/title)[index-of(/root/product/title,.)[1]]
let $ProductsProp := /root/product[title=$title]/properties/value
return 
<product>
    {$title}
    <image>{string(($ProductsProp[@key='product_image_url'])[1])}</image>
    <networks>{
        for $network in /root/package/properties
                                  [value[@key='main_product']
                                   = $ProductsProp[@key='product_code']]
                                  /value[@key='network_code']/string()
        return
        <network>{$network}</network>
    }</networks>
    <colours>{
        for $colour in $ProductsProp[@key='colour']/string()
        return
        <colour>{$colour}</colour>
    }</colours>
</product>

Output:

<product>
    <title>Acer Liquid</title>
    <image>ACER-LIQUID.jpg</image>
    <networks>
        <network>O2O</network>
        <network>VOD</network>
    </networks>
    <colours>
        <colour>Blue</colour>
        <colour>Black</colour>
    </colours>
</product>

Note: XPath 2.0 grouping expression $vSeq[index-of($vSeq,.)[1]]

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文