Search code examples
xmlxquery

Insert a new element into an XML document using XQuery 3.0


I need to insert a new element inside multiple nodes into an input XML document. Then, I need to update and retrieve the updated XML document.

I'm using Anypoint Studio, and since the xquery Transformation module supports XQuery 3.0, I figured that I can use the insert-before function, and since the element must be inserted in multiple nodes, I need to use a for loop to cycle through the multiple matches.

I'm new to xQuery so I apologize in advance for any beginner-type errors.

Here's a sample of the XML document I need to transform:

<Catalog>
  <Item>
    <Property1>Prop1</Property1>
    <Property2>Prop2</Property2>
    <Property3>Prop3</Property3>
  </Item>
  <Item>
    <Property1>Prop1</Property1>
    <Property2>Prop2</Property2>
    <Property3>Prop3</Property3>
  </Item>
  <Item>
    <Property1>Prop1</Property1>
    <Property2>Prop2</Property2>
    <Property3>Prop3</Property3>
  </Item>
</Catalog>

I need to insert the tag Name in position 1 of every Item node. Something like this:

<Catalog>
  <Item>
    <Name>SomeName1</Name>
    <Property1>Prop1</Property1>
    <Property2>Prop2</Property2>
    <Property3>Prop3</Property3>
  </Item>
  <Item>
    <Name>SomeName2</Name>
    <Property1>Prop1</Property1>
    <Property2>Prop2</Property2>
    <Property3>Prop3</Property3>
  </Item>
  <Item>
    <Name>SomeName3</Name>
    <Property1>Prop1</Property1>
    <Property2>Prop2</Property2>
    <Property3>Prop3</Property3>
  </Item>
</Catalog>

I tried many queries, but got syntax errors every time, due to my poor knowledge of XQuery. For example, I tried this query:

xquery version "3.0";
declare copy-namespaces no-preserve, inherit;
declare variable $document external;

declare variable $items := $document/Catalog/Item;

for $item in $items
return
   <Item>
     <Name>{ }</Name>
     { $item/Property1 } 
     { $item/Property2 }
     { $item/Property3 }
   </Item>

...but the resulting XML document (an array of string using the xquery transformation module in anypoint Studio) doesn't contain the root node.

Any help would be greatly appreciated.


Solution

  • I don't have Mulesoft and its Anypoint Studio.

    I am using BaseX v.9.5.1

    XQuery

    declare context item := document {
    <Catalog>
      <Item>
        <Property1>Prop1</Property1>
        <Property2>Prop2</Property2>
        <Property3>Prop3</Property3>
      </Item>
      <Item>
        <Property1>Prop1</Property1>
        <Property2>Prop2</Property2>
        <Property3>Prop3</Property3>
      </Item>
    </Catalog>
    };
    
    <Catalog>
    {
      let $new := <newElement>somevalue</newElement>
      for $x in ./Catalog/Item
      return <Item>
        {$new, $x/*}
      </Item>
      
    }
    </Catalog>
    

    Output

    <Catalog>
      <Item>
        <newElement>somevalue</newElement>
        <Property1>Prop1</Property1>
        <Property2>Prop2</Property2>
        <Property3>Prop3</Property3>
      </Item>
      <Item>
        <newElement>somevalue</newElement>
        <Property1>Prop1</Property1>
        <Property2>Prop2</Property2>
        <Property3>Prop3</Property3>
      </Item>
    </Catalog>