xmlxpathxml-parsingxqueryflwor

How to count specific elements in an XML file using FLWOR?


I'm looking to count the sum of all tags Order in Orders for the sample xml below. The total sum.

How can I return the number of element tags foo? Here, a sort of count is:

1
1

whereas I'm looking for the sum only: 2.

query:

for $i in doc("foo.xml")/windward-studios/Orders/Order
return count($i)

sample xml:

<windward-studios>
  <Orders>
    <Order OrderID="10248">
      <CustomerID>VINET</CustomerID>
      <EmployeeID>5</EmployeeID>
      <OrderDate>1996-07-04T14:25:55</OrderDate>
      <RequiredDate>1996-08-01T06:43:44</RequiredDate>
      <ShippedDate>1996-07-16T04:00:12</ShippedDate>
      <ShipVia>3</ShipVia>
      <Freight>32.3800</Freight>
      <ShipName>Vins et alcools Chevalier</ShipName>
      <ShipAddress>59 rue de l'Abbaye</ShipAddress>
      <ShipCity>Reims</ShipCity>
      <ShipRegion/>
      <ShipPostalCode>51100</ShipPostalCode>
      <ShipCountry>France</ShipCountry>
      <OrderDetails>
        <OrderDetail>
          <ProductID>11</ProductID>
          <UnitPrice>14.0000</UnitPrice>
          <Quantity>12</Quantity>
          <Discount>0</Discount>
        </OrderDetail>
        <OrderDetail>
          <ProductID>42</ProductID>
          <UnitPrice>9.8000</UnitPrice>
          <Quantity>10</Quantity>
          <Discount>0</Discount>
        </OrderDetail>
        <OrderDetail>
          <ProductID>72</ProductID>
          <UnitPrice>34.8000</UnitPrice>
          <Quantity>5</Quantity>
          <Discount>0</Discount>
        </OrderDetail>
      </OrderDetails>
    </Order>
    <Order OrderID="10249">
      <CustomerID>TOMSP</CustomerID>
      <EmployeeID>6</EmployeeID>
      <OrderDate>1996-07-05T06:39:18</OrderDate>
      <RequiredDate>1996-08-16T03:39:38</RequiredDate>
      <ShippedDate>1996-07-10T14:39:39</ShippedDate>
      <ShipVia>1</ShipVia>
      <Freight>11.6100</Freight>
      <ShipName>Toms Spezialitäten</ShipName>
      <ShipAddress>Luisenstr. 48</ShipAddress>
      <ShipCity>Münster</ShipCity>
      <ShipRegion/>
      <ShipPostalCode>44087</ShipPostalCode>
      <ShipCountry>Germany</ShipCountry>
      <OrderDetails>
        <OrderDetail>
          <ProductID>14</ProductID>
          <UnitPrice>18.6000</UnitPrice>
          <Quantity>9</Quantity>
          <Discount>0</Discount>
        </OrderDetail>
        <OrderDetail>
          <ProductID>51</ProductID>
          <UnitPrice>42.4000</UnitPrice>
          <Quantity>40</Quantity>
          <Discount>0</Discount>
        </OrderDetail>
      </OrderDetails>
    </Order>
  </Orders>
</windward-studios>

Solution

  • You were iterating over each of the Order elements and then asking for the count of each element.

    Instead, ask for the count of the Order elements:

    let $orders := doc("foo.xml")/windward-studios/Orders/Order
    return count($orders)
    

    You can do this more simply without a FLWOR:

    count(doc("foo.xml")/windward-studios/Orders/Order)