Kim
Kim

Reputation: 15

How to change values and create new elements?

I'm new to XQuery. Is there any way to use XQuery to turn this input

<mods>
    <subject>
        <topic> bird ; cat ; dog ; lion </topic>
    </subject>
</mods>

into following XML?

<mods>
    <subject>
        <topic> bird </topic><topic> cat </topic><topic> dog </topic><topic> lion </topic>
    </subject>
</mods>

I tried to use the function

replace(node,';','</topic><topic>' )

but it turns the angle < > brackets into its entity reference &lt; or &gt;.

Upvotes: 1

Views: 52

Answers (2)

Christian Gr&#252;n
Christian Gr&#252;n

Reputation: 6229

If your XQuery Processor supports XQuery Update, you can try the following query:

copy $xml := document {
  <mods>
    <subject>
        <topic> bird ; cat ; dog ; lion </topic>
    </subject>
  </mods>
}
modify (
  let $topic := $xml/mods/subject/topic
  return replace node $topic with
    for $token in tokenize($topic, ';')
    return <topic>{ $token }</topic>
)
return $xml

Upvotes: 2

Jens Erat
Jens Erat

Reputation: 38682

replace(...) only works on strings, not on elements. '</topic><topic>' (a string) and </topic><topic> (invalid XML) are not the same!

Reconstruct the result (you might also be able to use XQuery Update), and tokenize each <topic/> element, creating new topic items for each of them:

element mods {
  element subject {
    for $topics in /mods/subject/topic
    for $topic in tokenize($topics, ';')
    return element topic { $topic }
  }
}

For constructing new elements, I prefer the computed element constructors used above. element nodeName { $content } is equivalent to using <nodeName>{ $content }</nodeName>.

Upvotes: 2

Related Questions