如何使用XQuery迭代XML文件来构建XML请求?

时间:2016-09-24 22:14:55

标签: xml xquery

我有一个xml文件,我必须迭代并构建一个请求文件。我写的XQuery没有迭代我所困的所有元素,如何包含那些有productCode != "NOT_AVAILABLE"

的lineitems
declare function local:constructSubscriberLineItems($LineItems){
    for $productCode in distinct-values($LineItems/LineItem/ProductCode)
    let $entries := $LineItems/LineItem[ProductCode = $productCode]
    let $notAvailable := $entries[ProductCode/text() = "NOT_AVAILABLE"]
    for $distinctProductType in distinct-values($notAvailable/ProductType)
    let $productType := $notAvailable[ProductType = $distinctProductType]
    for $distinctBillingCode in distinct-values($productType/BillingCode)
    let $BillingCode := $productType[BillingCode = $distinctBillingCode] 
    let $subscriberLineItemDetails :=

    <subscriberLineItemDetails>
        <productType>{distinct-values($BillingCode/ProductType/text())}</productType>
        <productCode>{distinct-values($BillingCode/ProductCode/text())}</productCode>
        <billingCode>{distinct-values($BillingCode/BillingCode/text())}</billingCode>
        <quantity>{sum($BillingCode/Quantity)}</quantity>
    </subscriberLineItemDetails>

    return $subscriberLineItemDetails
};

示例XML

<LineItems>
    <LineItem>
        <Id>01</Id>
        <ProductCode>prod123456</ProductCode>
        <BillingCode>CHE001</BillingCode>
        <ProductType>HARDGOOD</ProductType>
        <Quantity>10</Quantity>
    </LineItem>
    <LineItem>
        <Id>02</Id>
        <ProductCode>prod123456</ProductCode>
        <BillingCode>CHE001</BillingCode>
        <ProductType>HARDGOOD</ProductType>
        <Quantity>10</Quantity>
    </LineItem>
    <LineItem>
        <Id>03</Id>
        <ProductCode>prod123456</ProductCode>
        <BillingCode>CHE001</BillingCode>
        <ProductType>HARDGOOD</ProductType>
        <Quantity>10</Quantity>
    </LineItem>
    <LineItem>
        <Id>04</Id>
        <ProductCode>prod6789</ProductCode>
        <BillingCode>CHE001</BillingCode>
        <ProductType>HARDGOOD</ProductType>
        <Quantity>4</Quantity>
    </LineItem>
    <LineItem>
        <Id>05</Id>
        <ProductCode>prod6789</ProductCode>
        <BillingCode>CHE001</BillingCode>
        <ProductType>HARDGOOD</ProductType>
        <Quantity>5</Quantity>
    </LineItem>
    <LineItem>
        <Id>06</Id>
        <ProductCode>prod6789</ProductCode>
        <BillingCode>CHE001</BillingCode>
        <ProductType>HARDGOOD</ProductType>
        <Quantity>7</Quantity>
    </LineItem>
    <LineItem>
        <Id>07</Id>
        <ProductCode>NOT_AVAILABLE</ProductCode>
        <BillingCode>BANG001</BillingCode>
        <ProductType>OPTIONAL_FEATURE</ProductType>
        <Quantity>7</Quantity>
    </LineItem>
    <LineItem>
        <Id>08</Id>
        <ProductCode>NOT_AVAILABLE</ProductCode>
        <BillingCode>BANG001</BillingCode>
        <ProductType>OPTIONAL_FEATURE</ProductType>
        <Quantity>7</Quantity>
    </LineItem>
    <LineItem>
        <Id>09</Id>
        <ProductCode>NOT_AVAILABLE</ProductCode>
        <BillingCode>TRV001</BillingCode>
        <ProductType>OPTIONAL_FEATURE</ProductType>
        <Quantity>7</Quantity>
    </LineItem>
    <LineItem>
        <Id>10</Id>
        <ProductCode>NOT_AVAILABLE</ProductCode>
        <BillingCode>BANG001</BillingCode>
        <ProductType>INCLUDED_FEATURE</ProductType>
        <Quantity>7</Quantity>
    </LineItem>
    <LineItem>
        <Id>11</Id>
        <ProductCode>NOT_AVAILABLE</ProductCode>
        <BillingCode>BANG001</BillingCode>
        <ProductType>INCLUDED_FEATURE</ProductType>
        <Quantity>7</Quantity>
    </LineItem>
    <LineItem>
        <Id>12</Id>
        <ProductCode>NOT_AVAILABLE</ProductCode>
        <BillingCode>TRV001</BillingCode>
        <ProductType>INCLUDED_FEATURE</ProductType>
        <Quantity>7</Quantity>
    </LineItem>
</LineItems>

预期产出

<subscriberLineItemDetails>
    <productType>HARDGOOD</productType>
    <productCode>prod123456</productCode>
    <billingCode>CHE001</billingCode>
    <quantity>30</quantity>
</subscriberLineItemDetails>
<subscriberLineItemDetails>
    <productType>HARDGOOD</productType>
    <productCode>prod6789</productCode>
    <billingCode>CHE001</billingCode>
    <quantity>16</quantity>
</subscriberLineItemDetails>
<subscriberLineItemDetails>
    <productType>OPTIONAL_FEATURE</productType>
    <productCode>NOT_AVAILABLE</productCode>
    <billingCode>BANG001</billingCode>
    <quantity>14</quantity>
</subscriberLineItemDetails>
<subscriberLineItemDetails>
    <productType>OPTIONAL_FEATURE</productType>
    <productCode>NOT_AVAILABLE</productCode>
    <billingCode>TRV001</billingCode>
    <quantity>7</quantity>
</subscriberLineItemDetails>
<subscriberLineItemDetails>
    <productType>INCLUDED_FEATURE</productType>
    <productCode>NOT_AVAILABLE</productCode>
    <billingCode>BANG001</billingCode>
    <quantity>14</quantity>
</subscriberLineItemDetails>
<subscriberLineItemDetails>
    <productType>INCLUDED_FEATURE</productType>
    <productCode>NOT_AVAILABLE</productCode>
    <billingCode>TRV001</billingCode>
    <quantity>7</quantity>
</subscriberLineItemDetails>

1 个答案:

答案 0 :(得分:0)

group by子句几乎肯定是你的朋友。看起来您想要聚合具有相同ProductCode的LineItems,并为“NOT_AVAILABLE”项目做一些不同的事情。我不完全得到你需要做的不同的不可用的(你是否需要根据其他一些值的组合来聚合那些),但下面的代码应该让你顺利。

for $items in LineItems/LineItem
group by $val := $items/ProductCode
return 
if ($val != 'NOT_AVAILABLE') then
    <subscriberLineItemDetails>
      <productType>{$items[1]/ProductType/text()}</productType>
      <productCode>{$val}</productCode>
      <billingCode>{$items[1]/BillingCode/text()}</billingCode>
    <quantity>{sum($items/Quantity)}</quantity>
  </subscriberLineItemDetails>
else
(: Different handling for NOT_AVAILABLE line items. You can add a group by clause for these as well 
   if you need to aggregate them in some way :)
for $item in $items
return
  <subscriberLineItemDetails>
    <productType>{$item/ProductType/text()}</productType>
    <productCode>{$item/ProductCode}</productCode>
    <billingCode>{$item/BillingCode/text()}</billingCode>
    <quantity>{sum($item/Quantity)}</quantity>
  </subscriberLineItemDetails>