使用xpath查询并选择分支

时间:2018-12-19 06:41:32

标签: xml xpath

我想获取一个XML文档,其中包含ZIP,2222和NAME = Meier的所有条目的NAME,FIRSTNAME和STR。

输入为:

<ROOT> 
<REC>
  <CONTACT>
    <NAME>Schmidt</NAME>
    <FIRSTNAME>Hans</FIRSTNAME>
  </CONTACT>
  <CONTACT>
    <NAME>Schmidt</NAME>
    <FIRSTNAME>Kurt</FIRSTNAME>
  </CONTACT>
  <LOC>
    <ZIP>1111</ZIP>
    <STR>Mainroud</STR>
  </LOC>
</REC>
<REC>
  <CONTACT>
    <NAME>Meier</NAME>
    <FIRSTNAME>Elise</FIRSTNAME>
  </CONTACT>
  <LOC>
    <ZIP>2222</ZIP>
    <STR>Castlestreet</STR>
  </LOC>
</REC>
</ROOT>

所需的输出:

 <OUT>
    <NAME>Meier</NAME>
    <FIRSTNAME>Elise</FIRSTNAME>
    <STR>Castlestreet</STR>
 </OUT>

我尝试过:

/ROOT/REC[.//ZIP="2222" and .//NAME/text()="Meier"]

哪个返回匹配的REC元素,但是如何格式化输出。 我只想使用Xpath,如果可能的话不使用Xquery?

3 个答案:

答案 0 :(得分:1)

您可以使用以下代码:

      let $input :=doc("input.xml")/ROOT/REC[.//ZIP="2222" and 
     .//NAME/text()="Meier"]
     return <OUT>{($input//NAME, $input//FIRSTNAME,  $input//STR)}</OUT>

答案 1 :(得分:1)

您能做的最好的事情是指定要在输出中包含哪些节点,但是这些节点将不会包含在<OUT>节点中,因为原始XML中没有这些节点。 如果需要特定节点的列表,则必须将XPath更改为类似这样的内容:

/ROOT/REC[.//ZIP="2222" and .//NAME/text()="Meier"]//(NAME|ZIP|STR)

哪个会给您以下结果:

<NAME>Meier</NAME>
<ZIP>2222</ZIP>
<STR>Castlestreet</STR>

结果是节点集合,而不是带有子节点的单个节点,您必须遍历该集合。并非完全是您要的,而是仅使用XPath就可以解决我的问题。

答案 2 :(得分:0)

另一个不错的解决方案是:

//REC[.//ZIP="2222" and .//NAME/text()="Meier"]
!<OUT>
  {.//NAME}
  {.//STR}
  {.//ZIP}
</OUT>