Xml XQuery-按属性提取不同的元素

Xml XQuery-按属性提取不同的元素,xml,xpath,xquery,exist-db,Xml,Xpath,Xquery,Exist Db,我有一个XML文档,其中包含客户及其订单和订单中项目的列表。我想得到一个包含不同客户价值观的列表。客户id是“名称”的属性。XML示例: <customerunion> <Customer Name="c2"> <Order OrderNumber="o1"> <Item Description="xyz">i10</Item> </Order> </Customer> &

我有一个XML文档,其中包含客户及其订单和订单中项目的列表。我想得到一个包含不同客户价值观的列表。客户id是“名称”的属性。XML示例:

<customerunion>
  <Customer Name="c2">
    <Order OrderNumber="o1">
      <Item Description="xyz">i10</Item>
    </Order>
  </Customer>

 <Customer Name="c3">
    <Order OrderNumber="o1">
      <Item Description="qwe">i11</Item>
      <Item Description="mnb">i12</Item>
    </Order>
    <Order OrderNumber="o2">
      <Item Description="cfg">i5</Item>
    </Order>
 </Customer>

 <Customer Name="c1">
    <Order OrderNumber="o1">
      <Item Description="abc">i1</Item>
      <Item Description="def">i2</Item>
    </Order>
 </Customer>

 <Customer Name="c4">
    <Order OrderNumber="o1">
      <Item Description="abc">i1</Item>
    </Order>
    <Order OrderNumber="o2">
      <Item Description="def">i2</Item>
    </Order>
 </Customer>

 <Customer Name="c2">
    <Order OrderNumber="o1">
      <Item Description="milk"/>
 </Order>
 </Customer>

 <Customer Name="c10">
    <Order OrderNumber="o1">
      <Item Description="chips greek yogort avacado"/>
    </Order>
 </Customer>

 <Customer Name="c4">
    <Order OrderNumber="o1">
      <Item Description="tea bags cheese"/>
    </Order>
 </Customer>

 <Customer Name="c11">
    <Order OrderNumber="o1">
      <Item Description=" milk sushi Notebook "/>
    </Order>
 </Customer>

 <Customer Name="c11">
    <Order OrderNumber="o2">
      <Item Description="grape tomato"/>
    </Order>
 </Customer>

 <Customer Name="c12">
    <Order OrderNumber="o1">
      <Item Description="bread"/>
    </Order>
 </Customer>
</customerunion>

i10
i11
i12
i5
i1
i2
i1
i2
下面是我想要得到的结果:

<customerlib>
  <Customer Name="c1">
    <Order OrderNumber="o1">
      <Item Description="abc">i1</Item>
      <Item Description="def">i2</Item>
    </Order>
  </Customer>

  <Customer Name="c2">
    <Order OrderNumber="o1">
      <Item Description="xyz">i10</Item>
    </Order>
  </Customer>

  <Customer Name="c3">
    <Order OrderNumber="o1">
      <Item Description="qwe">i11</Item>
      <Item Description="mnb">i12</Item>
    </Order>
    <Order OrderNumber="o2">
      <Item Description="cfg">i5</Item>
    </Order>
  </Customer>
  <Customer Name="c4">
    <Order OrderNumber="o1">
      <Item Description="abc">i1</Item>
    </Order>
    <Order OrderNumber="o2">
      <Item Description="def">i2</Item>
    </Order>
  </Customer>
  <Customer Name="c10">
    <Order OrderNumber="o1">
      <Item Description="chips">i1</Item>
      <Item Description="greek yogort">i2</Item>
      <Item Description="avacado">i3</Item>
    </Order>
  </Customer>

  <Customer Name="c11">
    <Order OrderNumber="o1">
      <Item Description="milk">i1</Item>
      <Item Description="sushi">i2</Item>
      <Item Description="Notebook">i3</Item>
    </Order>
    <Order OrderNumber="o2">
      <Item Description="grape tomato">i1</Item>
    </Order>
  </Customer>

  <Customer Name="c12">
    <Order OrderNumber="o1">
      <Item Description="bread">i1</Item>
    </Order>
  </Customer>
</customerlib>

i1
i2
i10
i11
i12
i5
i1
i2
i1
i2
i3
i1
i2
i3
i1
i1
我使用了以下XQuery:

let $customer := doc("customerunion.xml")/customerunion/Customer
let $allcustomername := doc("customerunion.xml")/Customer/@Name
for $uniquecustomer in distinct-values($customer/@Name)
let $order := distinct-values($customer[Name=$uniquecustomer]/Order)
let $item := distinct-values($customer[Name=$uniquecustomer]/Order/Item)
where $uniquecustomer = $allcustomername
return 
 <customerlib>
    {$uniquecustomer/..}
    {
      for $o in $order
      return $o
    }
    {
      for $i in $item
      return $i
    }
 </customerlib>
let$customer:=doc(“customerunion.xml”)/customerunion/customer
让$allcustomername:=doc(“customerunion.xml”)/Customer/@Name
对于具有不同值的$uniquecustomer($customer/@Name)
let$order:=不同的值($customer[Name=$uniquecustomer]/order)
let$item:=不同的值($customer[Name=$uniquecustomer]/Order/item)
其中$uniquecustomer=$allcustomername
返回
{$uniquecustomer/.}
{
在$order中的$o
返回$o
}
{
对于$i,在$item中
返回$i
}

但是,运行查询没有得到任何结果。您能帮我修改XQuery以获得所需的结果吗?

如果我理解正确,您似乎要求将所有订单分组为不同的客户

如果是这样,您可以在eXist db中使用XQuery 3.0中的
group by
表达式。因此,以下查询应该适用于您:

<customerlib>
{
    let $customers := doc("customerunion.xml")
    return
        for $customer in $customers/customersunion/Customer
        group by $customer-name := $customer/@Name
        order by substring-after($customer-name, "c") cast as xs:integer
        return
            <Customer Name="{$customer-name}">
            {
                $customers/customersunion/Customer[@Name eq $customer-name]/Order
            }
            </Customer>
}
</customerlib>

{
让$customers:=doc(“customerunion.xml”)
返回
适用于$customers/customersunion/customer中的$customer
按$customer name分组:=$customer/@name
按($customer name,“c”)后的子字符串排序转换为xs:integer
返回
{
$customers/customersunion/Customer[@Name eq$Customer Name]/订单
}
}

我还添加了一个orderby表达式,因为您显示的结果是有序的。然而,这是基于这样一个事实,即您的客户名称的格式始终是
cN
,其中N是一些数字。如果不是这样的话,你需要调整或删除查询中的那一行。

一方面,XQuery的第一行有<代码> /CuultUng/<代码>,而XML有<代码> <代码>:元素名称中间有一个<代码> s >代码>。您的第二个
let
语句完全省略了
/customersunion/
。由于这些原因,前两个变量将不包含任何内容。请在提问之前进行一些基本调试。只运行第一行(并返回结果),如果没有问题,继续下一行(或逻辑代码块,或任何合理的基本单元)。要添加到Jens的正确注释中,您可能有兴趣了解
fn:trace()
函数,您可以使用它进行调试。感谢大家的帮助。