使用带有多个表达式的祖先或自我选择 text() XSLT XPATH

Posted

技术标签:

【中文标题】使用带有多个表达式的祖先或自我选择 text() XSLT XPATH【英文标题】:selecting text() using ancestor-or-self with multiple expressions XSLT XPATH 【发布时间】:2020-01-03 21:35:52 【问题描述】:

给定 XML:

<surmat>
  <unpack>
     <proc>
        <para>SERVICE UPON RECEIPT</para>
     </proc>
     <proc>
         <title></title>
         <para>Lift and remove</para>
     </proc>
   </unpack>
<surmat>

&lt;surmat&gt; 有三个孩子unpack | chkeqp | processeqp 所以xml也可以是

<surmat>
  <processeqp>
     <proc>
        <para>SERVICE UPON RECEIPT</para>
     </proc>
     <proc>
         <title></title>
         <para>Lift and remove</para>
     </proc>
   </processeqp>
<surmat>

<surmat>
      <chkeqp>
         <title>SERVICE UPON RECEIPT</title>
         <proc>
             <title></title>
             <para>Lift and remove</para>
         </proc>
       </chkeqp>
    <surmat>

使用 XPATH 或 XSLT 2.0 我只想检查 &lt;unpack&gt;&lt;chkeqp&gt;&lt;processeqp&gt; 的第一个子级中的 SERVICE UPON RECEIPT 是否存在来自 &lt;title&gt; 模板和 &lt;unpack/chkeqp/processeqp&gt; 模板,因为 @ 987654332@ 是可选的。 (如果缺少任何一个,我必须插入 SERVICE... 和/或标题标签。)chkeqp 的子代不同于 unpackprocesseqp

这将按预期返回true

contains(upper-case(ancestor-or-self::*[unpack or chkeqp or processeqp]),'SERVICE UPON RECEIPT')

但我只需要检查第一个孩子,我无法弄清楚使用 text() 的语法。

即这不起作用:

contains(upper-case(ancestor-or-self::*[unpack or chkeqp or processeqp]/text()[1]),'SERVICE UPON RECEIPT')

或这个的变体:

contains(upper-case(ancestor-or-self::*[unpack or chkeqp or processeqp]/proc/para/text()[1]),'SERVICE UPON RECEIPT')

如果有更有效的方法,我将不胜感激!谢谢。

这个答案解决了我的问题:

contains(upper-case(ancestor-or-self::*[(self::unpack or self::chkeqp or self::processeqp) and count(preceding-sibling::*[self::unpack or self::chkeqp or self::processeqp])=0]/descendant-or-self::para[1]),'SERVICE UPON RECEIPT')

【问题讨论】:

【参考方案1】:

要检查祖先元素是否是surmat 的第一个子元素,您可以计算preceding-siblings:

contains(upper-case(ancestor-or-self::*[(self::unpack or self::chkeqp or self::processeqp) and count(preceding-sibling::*[self::unpack or self::chkeqp or self::processeqp])=0]/descendant-or-self::para[1]),'SERVICE UPON RECEIPT')

此表达式仅返回 true 匹配第一个 para 元素的文本,该元素是 title 元素的祖先 unpackchkeqpprocesseqp 元素的后代。

【讨论】:

【参考方案2】:

我不确定我是否正确理解了您的问题,但是鉴于您的 xml,以下 xpath

contains(upper-case(//ancestor-or-self::*[name()=('unpack','chkeqp', 'processeqp')]/*[1]//para/text()),'SERVICE UPON RECEIPT')

返回

是的

这就是你所追求的吗?

【讨论】:

我想是的,谢谢,我将在星期二进行测试。我不想使用para,因为chkeqp 的标签在同一位置可能没有para

以上是关于使用带有多个表达式的祖先或自我选择 text() XSLT XPATH的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用祖先或自我的情况下构建祖先树:: *

xsl 祖先或自我不返回结果

csharp 祖先或自我

如何使用 XML::Twig 显示祖先?

是否可以创建导航祖先的自定义 jQuery 选择器?例如:closest 或 :parents 选择器

使用 jQuery 和 CSS 选择器选择嵌套元素的共同父/祖先