首页 文章

XPath表达式忽略带有引用子元素的谓词的名称空间

提问于
浏览
0

我正在开发一个迄今为止依赖于设置的项目: DocumentBuilderFactory.setNamespaceAware(false); 实现名称空间灵活的xpath(忽略可传入的任何前缀) .

这只在过去工作,因为正在使用xalan转换器,虽然从技术上讲,设置名称空间感知到false的行为应该是最好的,对于给定的xml,xalan将以下xpath视为有效 .

XML:

<t:GiftBasket xmlns:t="http://tastyTreats.com/giftbasket">
    <t:Fruit>
        <t:Apple>
            <t:Name>Cameo</t:Name>
            <t:Color>Red</t:Color>
            <t:TasteDescription>Juicy, crisp, and sweet with just a touch of tart, the Cameo is thought to come from both the Red and the Yellow Delicious.</t:TasteDescription>
        </t:Apple>
        <t:Apple>
            <t:Name>Empire</t:Name>
            <t:Color>Red</t:Color>
            <t:TasteDescription>The interior is crisp and creamy white while being firmer than the McIntosh, so it makes for a good cooking apple. </t:TasteDescription>
        </t:Apple>
        <t:Apple>
            <t:Name>Granny Smith</t:Name>
            <t:Color>Green</t:Color>
            <t:TasteDescription>Hard feel, crisp bite, and extremely tart taste. Some prefer to cook it, which sweetens it up.</t:TasteDescription>
        </t:Apple>
    </t:Fruit>
    <t:Candy>
        <t:Chocolate>Dark</t:Chocolate>
    </t:Candy>
</t:GiftBasket>

XPath的:

/GiftBasket/Fruit/Apple[Color='Red'][contains(TasteDescription,'sweet')]

在切换到xslt 2.0时,我切换到了Saxon-HE变压器 . 撒克逊是一个更精确的变压器(IMO的好东西) . 它认识到这些xpath表达式是"wrong",我现在必须修复一堆像上面这样的xpath表达式,无论引用的名称空间前缀如何(客户端可以选择将URI http://tastyTreats.com/giftbasket作为'fluffybunnies'作为我知道的所有前缀)

关于如何利用 local-name() 函数来实现我需要的大部分功能,我收到了其他好的建议here . 我的xpath现在写道:

/*[local-name()='GiftBasket']/*[local-name()='Fruit']/*[local-name()='Apple'][Color='Red'][contains(TasteDescription,'sweet')]

但是,这仍然不准确,因为谓词中引用的元素仍然引用了精确的元素名称 ColorTasteDescription 而没有名称空间灵活性 . 是否有更好的方法为所有在其口味描述中包含'sweet'的红苹果编写xpath,同时保持名称空间前缀灵活?

1 回答

  • 1

    当你提到XSLT 2.0时,你可以在XSLT 2.0中定义

    <xsl:stylesheet xpath-default-namespace="http://tastyTreats.com/giftbasket" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    

    然后使用没有前缀名称的XPath表达式和XSLT匹配模式来选择该特定命名空间中的元素,也就是说,路径 /GiftBasket/Fruit/Apple[Color='Red'][contains(TasteDescription,'sweet')] 应该可以正常工作,以使用命名空间 http://tastyTreats.com/giftbasket 选择输入文档中的元素 .

    如果您将JAXP XPath API与Saxon 9一起使用,请参阅https://saxonica.plan.io/boards/3/topics/1649,了解如何使用该API设置此类默认命名空间:

    ((XPathEvaluator)xpath).getStaticContext().setDefaultElementNamespace("http://tastyTreats.com/giftbasket");
    

相关问题