【问题标题】:How to conditionally select a node in XPath如何有条件地选择 XPath 中的节点
【发布时间】:2014-02-14 17:59:07
【问题描述】:

我正在使用的 XSD 架构需要国际或国内地址:

"/mns:PhysicalAddress/mns:DomesticAddress/mns:City"

"/mns:PhysicalAddress/mns:InternationalAddress/mns:City"

它被用作 Java 方法中的参数,如 XMLUtils.BuildField(Document doc, String xpath)

我知道我可以直接访问创建 doc 的 Java 对象并使用自动生成的 bean 来查询元素,但我更喜欢保留在 XPath 的简洁领域内。这可能吗?

如果是这样,无论是国际地址还是国内地址,我如何编写一个选择mns:City 的XPath 表达式?

注意:这在 Java 中,而不是 Javascript、HTML 或 XSLT,所以我认为 <xsl:if> 与这里无关。

【问题讨论】:

    标签: java xml xpath xsd


    【解决方案1】:

    您可以查找所有具有任一父级的城市:

    //mns:City[(parent::mns:DomesticAddress|parent::mns:InternationalAddress)]
    

    如果还需要确保地址在物理地址中:

    //mns:City[(parent::mns:DomesticAddress|parent::mns:InternationalAddress)[parent::mns:PhysicalAddress]]
    

    或者,您不颠倒层次结构,而是执行* 并检查名称:

    /mns:PhysicalAddress/*[name()="mns:DomesticAddress" or name()="mns:InternationalAddress"]/mns:City
    

    【讨论】:

    • 谢谢!您放在那里的表达式是否代替了我原来的xpath 中的单个/mns:City?还是它是独立的?我以前从未见过这种“反向层次结构”,这就是我问的原因。暂时 +1,一旦我得到测试,我会接受。
    • 它是独立的(即完全取代您当前的 xpath)。我不相信反向层次结构很常见。我只看到它用于这种需要在节点上执行or 的场景。
    • 好的,想出了如何向下层级 - 见最后一个例子。
    【解决方案2】:

    取决于您的 XML 的精确结构,

    /mns:PhysicalAddress/*/mns:City
    

    可能就足够了,如果这太多了,那么最明确的选择可能就是使用您已经拥有的两个替代方案,用|分隔:

    /mns:PhysicalAddress/mns:DomesticAddress/mns:City | /mns:PhysicalAddress/mns:InternationalAddress/mns:City
    

    或者稍微简洁一些,但(在我看来)不太清楚:

    /mns:PhysicalAddress/*[self::mns:DomesticAddress | self::mns:InternationalAddress]/mns:City
    

    【讨论】:

    • 谢谢!这看起来比以前的建议更简洁,我喜欢它。 “只使用你已有的两个选项,用 | 分隔”,你的意思是"/mns:PhysicalAddress/mns:DomesticAddress|mns:InternationalAddress/mns:City"
    • @WinWin 如果您有 XPath 2.0,那么您可以使用 /mns:PhysicalAddress/(mns:DomesticAddress|mns:InternationalAddress)/mns:City,但如果您被限制为 1.0,那么您将不得不合并整个路径(或者使用 @987654327 做一个技巧@axis),我已经用一个例子编辑了答案。
    猜你喜欢
    • 2011-05-30
    • 1970-01-01
    • 2020-01-20
    • 2010-11-22
    • 2012-06-24
    • 2011-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多