【问题标题】:How to get node value using variable node name?如何使用变量节点名称获取节点值?
【发布时间】:2012-02-03 12:39:02
【问题描述】:

我有一个 XML 文档,例如:

<data>
    <item type="apple">
        <misc>something</misc>
        <appleValue>23</appleValue>
        <misc2>something else</misc2>
    </item>
    <item type="banana">
        <bananaValue>47</bananaValue>
        <random>something</random>
    </item>
</data>

我可以使用doc("data.xml")/data/item 获取项目,但我需要从以Value 结尾的元素中获取文本。所以我想得到“23”和“47”,但我不一定知道元素名称,这意味着我真正知道的是有以Value结尾的元素,我不知道是不是@ 987654325@、bananaValue 等,除了我可以查看type 属性并建立一个字符串。

let $type := (doc("data.xml")/data/item)[1]/@type
doc("data.xml")/data/item/$typeValue

...最后一行是我想要了解的内容,显然这不正确,但我需要根据变量(存储在 $type 等变量中)和“价值”。

有什么想法吗?我意识到这个变量元素的命名很奇怪/奇怪/不好......但这就是它的方式,我必须处理它。

【问题讨论】:

    标签: xpath xquery


    【解决方案1】:

    感谢这篇文章:Can XPath match on parts of an element's name?

    doc("data.xml")/data/item/*[ends-with(name(), "Value")]
    

    【讨论】:

      【解决方案2】:

      我会避免使用name() 函数来支持node-name() 或local-name()。这样做的原因是 name() 可以根据源中使用什么(以及是否)命名空间前缀来给你不同的答案。例如,以下三个元素具有相同的确切名称 (QName):

      <appleValue xmlns="http://example.com"/>
      <x:appleValue xmlns:x="http://example.com"/>
      <y:appleValue xmlns:y="http://example.com"/>
      

      但是,name() 函数将为您提供不同的答案(分别为appleValue、x:appleValue 和 y:appleValue)。所以你最好要么通过使用local-name()(对于上述所有三种情况都返回字符串appleValue)来忽略命名空间,要么使用@987654333显式指定命名空间(即使它是空的,如Oliver所示) @(返回正确的 QName 值,而不是字符串)。在这种情况下,由于您没有使用命名空间(而且即使您稍后添加,代码仍然可以工作),我会稍微支持使用local-name(),如下所示:

      doc("data.xml")/data/item/*['Value' eq substring-after(local-name(),../@type)]
      

      有关避免使用name() 功能(和异常)的详细说明,请参阅"Perils of the name function"。

      【讨论】:

        【解决方案3】:

        您可以使用name() 访问节点的名称。 XPath 1.0 没有“ends-with”功能,但通过使用substring() 和string-length() - 1 你可以到达那里。

        //item/*[ substring(  name(),  string-length(name() ) - 4  ) = 'Value']
        

        【讨论】:

          【解决方案4】:

          更精确的实现方式是

          for $item in doc("data.xml")/data/item
          let $value-name := fn:QName('', concat($item/@type, 'Value'))
          return $item/*[node-name() = $value-name]
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-12-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-08-06
            • 1970-01-01
            • 2012-03-06
            相关资源
            最近更新 更多