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

使用XQuery 3.0在XML文档中插入新元素,xml,xquery,Xml,Xquery,我需要在输入XML文档的多个节点中插入新元素。然后,我需要更新和检索更新后的XML文档 我使用的是Anypoint Studio,由于xquery转换模块支持xquery 3.0,我想我可以使用insert before函数,并且由于元素必须插入到多个节点中,我需要使用for循环来循环多个匹配 我是xQuery的新手,所以我为任何初学者类型的错误提前道歉 以下是我需要转换的XML文档示例: <Catalog> <Item> <Property1>P

我需要在输入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>

建议1
建议2
建议3
建议1
建议2
建议3
建议1
建议2
建议3
我需要在每个项目节点的位置1插入标记名称。 大概是这样的:

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

名字1
建议1
建议2
建议3
某人2
建议1
建议2
建议3
某某
建议1
建议2
建议3
我尝试了很多查询,但每次都会出现语法错误,这是因为我对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>
xquery版本“3.0”;
声明复制命名空间不保留、继承;
对外声明变量$document;
声明变量$items:=$document/Catalog/Item;
对于$items中的$item
返回
{ }
{$item/Property1}
{$item/Property2}
{$item/Property3}
…但生成的XML文档(使用anypoint Studio中的xquery转换模块的字符串数组)不包含根节点


任何帮助都将不胜感激。

我没有Mulesoft及其Anypoint工作室

我使用的是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>
声明上下文项:=文档{
建议1
建议2
建议3
建议1
建议2
建议3
};
{
让$new:=somevalue
$x英寸/目录/项目
返回
{$new,$x/*}
}
输出

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

一些价值
建议1
建议2
建议3
一些价值
建议1
建议2
建议3

我没有Mulesoft及其Anypoint工作室

我使用的是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>
声明上下文项:=文档{
建议1
建议2
建议3
建议1
建议2
建议3
};
{
让$new:=somevalue
$x英寸/目录/项目
返回
{$new,$x/*}
}
输出

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

一些价值
建议1
建议2
建议3
一些价值
建议1
建议2
建议3

您不需要在之前插入,但是

/*!element { node-name() } {
    Item ! element { node-name() } {
        insert-before(*, 1, <Name/>)
    }
}
/*!元素{node-name()}{
Item!元素{node-name()}{
在(*,1,)之前插入
}
}
这是使用它的一种方式,尽管

/*!element { node-name() } {
    Item ! element { node-name() } {
        <Name/>, *
    }
}
/*!元素{node-name()}{
Item!元素{node-name()}{
, *
}
}
他做这项工作


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

您不需要在
之前插入
,但是

/*!element { node-name() } {
    Item ! element { node-name() } {
        insert-before(*, 1, <Name/>)
    }
}
/*!元素{node-name()}{
Item!元素{node-name()}{
在(*,1,)之前插入
}
}
这是使用它的一种方式,尽管

/*!element { node-name() } {
    Item ! element { node-name() } {
        <Name/>, *
    }
}
/*!元素{node-name()}{
Item!元素{node-name()}{
, *
}
}
他做这项工作


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

请编辑您的帖子,并添加您已经尝试过的XQuery。您希望插入哪个元素,具体位置是哪里?至少显示要创建的XML结果。如果您不熟悉XQuery,在尝试将其与更复杂的输入和多个节点一起使用之前,可以先从使用
insert-before
的工作示例开始。如果您尝试了某些操作,请显示确切的代码和您遇到的确切错误。是的,对不起。我想在每个节点的位置1插入标记。我编辑这篇文章是为了进一步澄清我的问题。请编辑你的文章,并添加你已经尝试过的XQuery。你想插入哪个元素,具体位置是哪里?至少显示要创建的XML结果。如果您不熟悉XQuery,在尝试将其与更复杂的输入和多个节点一起使用之前,可以先从使用
insert-before
的工作示例开始。如果您尝试了某些操作,请显示确切的代码和您遇到的确切错误。是的,对不起。我想在每个节点的位置1插入标记。我编辑了这篇文章来进一步澄清我的问题。很好的回答,+1来自我这边!我也要试试这个。谢谢回答得很好,+1来自我这边!我也要试试这个。谢谢这个解决方案解决了这个问题。非常感谢@Yitzhak这个解决方案解决了这个问题。非常感谢@yitzhak