XPath concat兄弟节点的所有匹配

时间:2015-11-04 16:08:32

标签: xpath saxon xpath-2.0

我没有找到类似线程的解决方案,所以我希望有人可以帮助我。我有如下XML(摘录):

<root>
<identificationInfo>
<MD_DataIdentification>
<descriptiveKeywords>
            <MD_Keywords>
                <keyword>
                    <gco:CharacterString>Atmospheric conditions</gco:CharacterString>
                </keyword>
                <type>
                    <MD_KeywordTypeCode codeListValue="theme"/>
                </type>
            </MD_Keywords>
        </descriptiveKeywords>
        <descriptiveKeywords>
            <MD_Keywords>
                <keyword>
                    <gco:CharacterString>Agriculture</gco:CharacterString>
                </keyword>
                <keyword>
                    <gco:CharacterString>Biodiversity</gco:CharacterString>
                </keyword>
                <type>
                    <MD_KeywordTypeCode codeListValue="socialBenefitArea"/>
                </type>
            </MD_Keywords>
        </descriptiveKeywords>

我想要的是连接类型和关键字的字符串,以便我获得一个如下所示的列表

theme:Atmospheric conditions
socialBenefitArea:Agriculture
socialBenefitArea:Biodiversity

我尝试了以下解决方案(可以使用XPath 1.0或XPath 2.0),但始终只返回第一个匹配'主题:大气条件'。

  • for $n in /*/gmd:identificationInfo/*/gmd:descriptiveKeywords/gmd:MD_Keywords return string-join(($n/gmd:type/*/@codeListValue, ':', $n/gmd:keyword/*/text()), '')
  • /*/gmd:identificationInfo/*/gmd:descriptiveKeywords/gmd:MD_Keywords/gmd:keyword/concat(*/text(), ':', ../gmd:type/*/@codeListValue)
  • //gmd:descriptiveKeywords/*/string-join((gmd:type/*/@codeListValue, gmd:keyword/*/text()[1]), ':')
  • //gmd:descriptiveKeywords/*/gmd:keyword/concat(following-sibling::gmd:type/*/@codeListValue, ':', ./*/text())

如果XPath看起来正确,我使用Saxon-HE 9.x在Java中执行此操作。

我发现的是评估返回一个String,而不是NODESET,我可能需要多个结果。哪个XPath会返回NODESET?

感谢您的帮助!

3 个答案:

答案 0 :(得分:0)

XPath 2.0表达式//gco:CharacterString/concat(ancestor::MD_Keywords/type/MD_KeywordTypeCode/@codeListValue, ':', .)返回(http://xsltransform.net/6r5Gh2U)三个字符串的序列

theme:Atmospheric conditions
socialBenefitArea:Agriculture
socialBenefitArea:Biodiversity

我不明白为什么要求节点集,因为XPath 2.0不返回节点集,而是返回节点序列或原始值。由于您的结果不包含在节点中,但您希望连接不同节点中包含的字符串,我不会看到输入中选择的节点如何帮助,如果您想创建新节点,则需要XSLT或XQuery。

答案 1 :(得分:0)

我怀疑关于字符串和节点集的混淆是因为您使用的是为XPath 1.0设计的JAXP API,并且不允许您利用XPath 2.0的全部灵活性。如果你想从XPath表达式返回一系列字符串,正如@Martin Honnen所建议的那样,那么你将需要使用s9api API:它处理完整的XPath 2.0数据模型。您无法使用JAXP和节点集结果来解决此限制,因为XPath不允许您创建新节点(仅选择现有节点),并且您想要的字符串与现有节点不对应。

但是,如果您真的受限于JAXP,那么您可以通过使用string-join()函数和一些合适的分隔符(例如换行符)来更改查询以将结果合并为单个字符串,以及通过在调用Java代码中进行标记来将其拆分为多个结果。

答案 2 :(得分:0)

只需使用

/*/*/*/*/MD_Keywords/keyword/*/concat(../../type/*/@codeListValue, ': ', .)
  

哪个XPath会返回NODESET?

Xpath 3.0表达式可以使用标准函数生成节点(-set),例如 parse-xml()parse-xml-fragment()