使用 XQuery 3.0 将新元素插入 XML 文档

Insert a new element into an XML document using XQuery 3.0

我需要将多个节点内的新元素插入到输入 XML 文档中。然后,我需要更新和检索更新后的 XML 文档。

我正在使用 Anypoint Studio,并且由于 xquery 转换模块支持 XQuery 3.0,我想我可以使用 insert-before 函数,并且由于元素必须插入多个节点,因此我需要使用 for 循环来循环多个匹配项。

我是 xQuery 的新手,所以对于任何初学者类型的错误,我提前表示歉意。

这是我需要转换的 XML 文档的示例:

<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>

我需要在每个 Item 节点的位置 1 中插入标签 Name。 像这样:

<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>

我尝试了很多查询,但由于我对 XQuery 的了解不足,每次都遇到语法错误。 例如,我试过这个查询:

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>

...但是生成的 XML 文档(使用 anypoint Studio 中的 xquery 转换模块的字符串数组)不包含根节点。

如有任何帮助,我们将不胜感激。

我没有 Mulesoft 及其 Anypoint Studio。

我正在使用 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>

输出

<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>

你不需要insert-before但是

/*!element { node-name() } {
    Item ! element { node-name() } {
        insert-before(*, 1, <Name/>)
    }
}

将是一种使用方式,尽管

/*!element { node-name() } {
    Item ! element { node-name() } {
        <Name/>, *
    }
}

完成任务。

请注意,如果您的处理器支持(例如 BaseX),XQuery 更新可能会更合适。