Xml XQuery-按属性提取不同的元素
我有一个XML文档,其中包含客户及其订单和订单中项目的列表。我想得到一个包含不同客户价值观的列表。客户id是“名称”的属性。XML示例: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> &
<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()
函数,您可以使用它进行调试。感谢大家的帮助。