【问题标题】:Getting XML element from nested child values via XPath通过 XPath 从嵌套子值中获取 XML 元素
【发布时间】:2018-04-12 14:07:11
【问题描述】:

我有一个如下所示的 XML 文件:

<PACKAGES>
    <PACKAGE>
        <SHORT-NAME>Element1</SHORT-NAME>
        <PACKAGES>
            <PACKAGE>
                <SHORT-NAME>Element2</SHORT-NAME>
                <ELEMENTS>
                    <MODULE>
                        <SHORT-NAME>Element3</SHORT-NAME>
                        <DESC>
                        </DESC>
                        <CATEGORY>Item</CATEGORY>
                    </MODULE>
                </ELEMENTS>
            </PACKAGE>
        </PACKAGES>
    </PACKAGE>
</PACKAGES>

我希望能够基于“Element3”的父项的 SHORT-NAMES 使用“Element3”的 SHORT-NAME 构建对 MODULE 元素的 XPath 查询......所以像这样:

//SHORT-NAME='Element1'.//SHORT-NAME='Element2'.//SHORT-NAME='Element3'

我已经尝试了上面的查询,但它似乎不起作用,不是一个有效的查询。我也试过这个:

//*[text()='Element1']//*[text()='Element2'] etc...

但是,这似乎不是一个有效的查询。

我希望它是可扩展的,以便特定查询可以是任何路径,但路径始终基于 SHORT-NAME 的文本值。

比如:

/Element1/SubElement2/SubSubElement3/SubSubSubElement4 

也可以查询。

重要说明:对于上述查询,我​​只想要 Element3 IF 它是 Element2 的子元素,它是 Element1 的子元素。如果 Element3 存在于文档的其他位置,我不想要那个节点。

我希望这是可能的。我只是没有构建正确的查询,但我什至不知道如何搜索该主题以尝试找到答案。

编辑: Andersson 下面提供的答案几乎 100% 适用于我的用例。该问题突出显示如下:

如果我仍然需要查询 /Element1/Element2/Element3 但我的 XML 如下所示:

<PACKAGES>
    <PACKAGE>
        <SHORT-NAME>Element1</SHORT-NAME>
        <PACKAGES>
            <PACKAGE>
                <SHORT-NAME>Element2</SHORT-NAME>
                <ELEMENTS>
                    <PACKAGE>
                    <SHORT-NAME>RandomElement</SHORT-NAME>
                        <MODULE>
                            <SHORT-NAME>Element3</SHORT-NAME>
                            <DESC>
                            </DESC>
                            <CATEGORY>Item</CATEGORY>
                        </MODULE>
                    </PACKAGE>
                </ELEMENTS>
            </PACKAGE>
        </PACKAGES>
    </PACKAGE>
</PACKAGES>

仍然返回 Element3,但是 Element3 的父级不是 Element2。这使事情变得更加复杂,我怀疑我需要创建一个函数来系统地搜索下一个子 SHORT-NAME 并检查是否满足 for 查询。除非可以修改 XPath 查询以满足上述用例。

【问题讨论】:

  • 在示例中,其他级别没有 module 项目。 //module会找到它
  • 当然这是一个好点。但是,我应该详细说明我要查询的每个节点实际上可能不同,而不是每次都特别是 MODULE。查询时只知道元素的路径(/Element1/Element2/Element3),不知道具体的类型。
  • 您能否阐明基于“Element3”父母的简称是什么意思?是否要将具有值"Element3" 的节点与值"Element2" 的值"Element2" 匹配,这是节点"Element1" 的后代?
  • 是的。我只想要 Element3,它是 Element2 的子元素,它是 Element1 的子元素。如果 Element3 存在于文档中的其他地方,我不想要那个。我会将此添加到帖子中,因为我认为这是我错过的关键点。
  • 我认为当你不知道级别和值是字符串和整数的连接时,你不能用单个查询来做到这一点。找到//*[SHORT-NAME='Element1'],然后找到.//*[SHORT-NAME='Element2']等,而xpath会返回项目

标签: java xml dom xpath


【解决方案1】:

这个 XPath,

//*[SHORT-NAME='Element3']

将选择所有具有SHORT-NAME 子元素且字符串值为Element3 的元素,无论其名称如何。

如果您希望指定目标元素的遗产,请将模式向上扩展至所需的级别:

//*[SHORT-NAME='Element1']//*[SHORT-NAME='Element2']//*[SHORT-NAME='Element3']

【讨论】:

  • 谢谢@Andersson!
  • 哇,是的,这成功了!我在正确的道路上(没有双关语)只是轻微的语法错误!
  • @bryken /Element1/SubElement2/SubSubElement3/SubSubSubElement4 怎么样?
  • 我主要是想说该解决方案应该是可扩展的,以便我可以提出这样的请求。上面的答案确实允许这样做。
  • 不幸的是,我需要回到这个答案。这个方案有个小问题……原来这个方案不保证Element2是Element1下的第一个出现的SHORT-NAME,或者Element3是Element2下的第一个出现的SHORT-NAME。我做了一个类似上面的查询,除了实际路径类似于/Element1/Element2/RandomElement/Element3,这不是我需要的正确路径。无论如何要保证在其父项下第一次出现的 SHORT-NAME 是查询中指定的内容?
猜你喜欢
  • 2018-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-14
相关资源
最近更新 更多