选择堂兄弟姐妹——即前兄弟姐妹和前兄弟姐妹的问题

selecting cousins - i.e. issues with both preceding and preceding-sibling

如果我有以下xml

<root>
  <house id="1">
    <occupant>
    </occupant>
    <occupant>
    </occupant>
  </house>
  <house id="2">
    <occupant>
    </occupant>
    <occupant>
    </occupant>
  </house>
</root>

我想数数(数数不是问题,xpath的构造才是问题,我会在最后附上一个更准确但更难解释的例子)前面的'cousins'作为 我处理 xslt

和以下 xslt (1.0)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
      <counts>
        <xsl:apply-templates select="root/house/occupant"/>
      </counts>
    </xsl:template>
  
    <xsl:template match="occupant">
      <previous>
        <xsl:value-of select="count(preceding::occupant)"/>
      </previous>
    </xsl:template>
</xsl:stylesheet>

我得到我想要的

<counts>
  <previous>0</previous>
  <previous>1</previous>
  <previous>2</previous>
  <previous>3</previous>
</counts>

但是如果占用者可以出现在 xml 树的其他位置,例如

,则这不起作用
<root>
  <house id="1">
    <occupant>
    </occupant>
    <occupant>
    </occupant>
    <next_door>
      <house id="2">
        <occupant>
        </occupant>
        <occupant>
        </occupant>
      </house>
    </next_door>
  </house>
  <house id="2">
    <occupant>
    </occupant>
    <occupant>
    </occupant>
  </house>
</root>

我对 'next_door' 不感兴趣,事实上我只对树中的 'cousins'(和兄弟姐妹)感兴趣,即 'root/house/occupant'[= 路径上的东西15=]

以上将计算任何占用者,前面的兄弟姐妹将只计算兄弟姐妹。

感觉要算了

/root/house/occupant[表示此节点在当前节点之前的某些谓词]


P.S。实际问题更像是这样,即从特定表亲中提取数据(但解释输出非常复杂,其中计数很好且易于解释)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
      <counts>
        <xsl:apply-templates select="root/house/occupant"/>
      </counts>
    </xsl:template>
  
    <xsl:template match="occupant">
      <previous_and_next>
        <previous>
          <xsl:copy-of select="(preceding::occupant)[1]"/>
        </previous>
        <next>
          <xsl:copy-of select="(following::occupant)[1]"/>
        </next>
      </previous_and_next>
    </xsl:template>
</xsl:stylesheet>

我会使用 xsl:number 例如

  <previous>
    <xsl:number count="root/house/occupant" level="any"/>
  </previous>

因为你想减一例如

  <previous>
    <xsl:variable name="count"><xsl:number count="root/house/occupant" level="any"/></xsl:variable>
    <xsl:value-of select="$count - 1"/>
  </previous>

到 select 在 XPath 1.0 中基于节点计数设置“except”操作,您可以使用

<xsl:template match="occupant">
  <previous>
    <xsl:variable name="self-and-following" select=". | following::occupant"/>
    <xsl:variable name="cousins" select="/root/house/occupant[count(. | $self-and-following) = count($self-and-following) + 1]"/>
    <xsl:value-of select="count($cousins)"/>
  </previous>
</xsl:template>

不清楚你到底想要什么。从 /root/house/occupant 路径上的 occupant 的上下文中,您可以 select 使用相同路径上的前面的占用者:

preceding-sibling::occupant | ../preceding-sibling::house/occupant"