Elmer Mirano
Elmer Mirano

Reputation: 11

How to properly generate an xml from xquery

I'm new to xquery and is trying to read different references on using the tool. I've been trying to play around testing and trying to generate some xml format messages but this one puzzles me. Here's my xQuery code:

Sample XQuery

declare variable $requestBody as element() external;
declare function VerifyOrderDetailTransformation($requestBody as element())
as element() {
    <msg>
        <header>
            <headtitle>This is the title</headtitle>
        </header>
        <dbody>
            {GenerateEquipmentListNodes($requestBody)} 
        </dbody>
    </msg>
};

declare function GenerateEquipmentListNodes($requestBody as element())
as element()* {

    let $titleList := (
        for $e in $requestBody//bookstore//book
            let $dTitle := $e/title/text()
            return 
               <theTitle>{$dTitle}</theTitle>
        )

    return 
       <dTitleList>
           {$titleList}
       </dTitleList>
};

VerifyOrderDetailTransformation($requestBody)

Sample XML

<bookstore>

<book category="COOKING">
    <title lang="en">Everyday Italian</title>
    <author>Giada De Laurentiis</author>
    <year>2005</year>
    <price>30.00</price>
</book>

<book category="CHILDREN">
    <title lang="en">Harry Potter</title>
    <author>J K. Rowling</author>
    <year>2005</year>
    <price>29.99</price>
</book>

<book category="WEB">
    <title lang="en">XQuery Kick Start</title>
    <author>James McGovern</author>
    <author>Per Bothner</author>
    <author>Kurt Cagle</author>
    <author>James Linn</author>
    <author>Vaidyanathan Nagarajan</author>
    <year>2003</year>
    <price>49.99</price>
</book>

<book category="WEB">
    <title lang="en">Learning XML</title>
    <author>Erik T. Ray</author>
    <year>2003</year>
    <price>39.95</price>
</book>

</bookstore>

And here's the output generated by running xQuery on the XML:

Current output

<msg> 
    <head> 
        <title>This is the title</title> 
    </head> 
    <body> 
        <dTitleList/> 
    </body> 
</msg>

Expected Output

<msg> 
    <head> 
        <title>This is the title</title> 
    </head> 
    <body> 
        <dTitleList> 
        <theTitle>Everyday Italian</theTitle>
        <theTitle>Harry Potter</theTitle>
        <theTitle>XQuery Kick Start</theTitle>
        <theTitle>Learning XML</theTitle>
        <dTitleList/> 
    </body> 
</msg>

My question is, what could I have probably missed?

Upvotes: 1

Views: 5332

Answers (1)

Jens Erat
Jens Erat

Reputation: 38732

There is some problem with your input: You're querying this XML:

<bookstore>
  <book>
    <!-- snip -->
  </book>
  <!-- snip -->
</bookstore>

The first part of your XPath query, namely $queryBody//bookstore, looks for all descendant elements which have an element <bookstore/> below - what return an empty result. $queryBody//bookstore won't do either, as the context already is on the <bookstore/> element.

For this reason, ommit //bookstore, so your this should be $queryBody//book.

Use this function with the changed XPath in it:

declare function local:GenerateEquipmentListNodes($requestBody as element())
as element()* {

    let $titleList := (
        for $e in $requestBody//book
            let $dTitle := $e/title/text()
            return 
               <theTitle>{$dTitle}</theTitle>
        )

    return 
       <dTitleList>
           {$titleList}
       </dTitleList>
};

One more remark: You should put your own functions into local: function namespace or define your own one. Using the default namespace is discouraged and not compatible with all processors. I changed it to the local:-namespace.

Upvotes: 1

Related Questions