【问题标题】:Preserving priority of operands in one-liner Xpath 1.0在单行 Xpath 1.0 中保留操作数的优先级
【发布时间】:2011-01-08 00:27:08
【问题描述】:

我无法真正正确地表述它,最好举个例子。

XML:

<?xml version="1.0" encoding="UTF-8"?>
<foo>
    <bar id="someId" class="someClass"/>
    <buz class="someClass" id="someId"/>
    <ololo class="someClass"/>
    <test id="someId"/>
</foo>

XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/*/*">
    <xsl:value-of select="@id | @class"/><xsl:text>&#xa;</xsl:text>
</xsl:template>

</xsl:stylesheet>

结果:

someId
someClass
someClass
someId

我需要什么

我需要保持属性的“优先级”,如我的 xpath 表达式中所述。

因此,如果我们将@id | @class 称为具有两个操作数的表达式,我需要不按文档顺序获取属性,而是按照表达式中指定两个操作数的顺序。

所以,结果应该是

someId
someId
someClass
someId

仅当@id 不存在时才应使用@class

我知道,它可以用条件逻辑来完成,但我真的对一个简短的解决方案很感兴趣,因为它很常见并用作 属性值模板

这可能很明显,我错过了优雅的人。

请注意,我说的是 XPath 1.0

【问题讨论】:

  • 好问题,+1。有关完整且非常简短的 XPath 1.0 单行代码,请参阅我的答案。 :)

标签: xslt xpath


【解决方案1】:

使用

@id | @class[not(../@id)]

此 XPath 表达式始终选择一个节点@id(如果存在),并且仅当 @id 不存在时才选择@class

所以这个转变

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:strip-space elements="*"/>

 <xsl:output method="text"/>

 <xsl:template match="foo/*">
  <xsl:value-of select="@id | @class[not(../@id)]"/>
  <xsl:text>&#xA;</xsl:text>
 </xsl:template>
</xsl:stylesheet>

应用于提供的 XML 文档时

<foo>
    <bar id="someId" class="someClass"/>
    <buz class="someClass" id="someId"/>
    <ololo class="someClass"/>
    <test id="someId"/>
</foo>

产生想要的正确结果

someId
someId
someClass
someId

【讨论】:

  • 谢谢,这很明显。我需要在凌晨 4 点停止工作。尽管如此,现实生活中的问题通常更复杂,因此可能会有更多条件,并且解决方案似乎对每个条件都有谓词。你能想到什么技巧来简化这个吗?
  • @Flack:引用爱因斯坦的话:“让它尽可能简单,但不要更简单”:) 这是实现必要逻辑的最小 XPath 表达式。它确实很短。只需将其与节点集成员资格或 Muenchian 分组进行比较。
  • @Dimitre。我理解这一点,答案就足够了。我只是想到了@id | 之类的案例@class[not(../@id)] | @foo[不是(../@id 或 ../@class)]。当然,它是合成的,因此没有必要讨论。我只是想哪里可以更干燥。
  • @Flack:没有更简单的方法可以用没有序列/列表数据类型的语言来表达序列。使用&lt;xsl:sort&gt; 可能会有一些技巧,但您想要的是 XPath。此外,使用&lt;xsl:sort&gt; 肯定比互斥节点选择的并集要长得多。
  • @Dimitre,明白了。感谢您的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多