XSLT:查找给定节点的编号

XSLT:查找给定节点的编号,xslt,Xslt,我有一个表示逻辑派生的XML结构,它如下所示: <derivation> <step name="foo"> <derive>[...]</derive> <by>[...]</by> </step> <step name="bar"> <derive>[...]</derive> <by> <from

我有一个表示逻辑派生的XML结构,它如下所示:

<derivation>
  <step name="foo">
    <derive>[...]</derive>
    <by>[...]</by>
  </step>
  <step name="bar">
    <derive>[...]</derive>
    <by>
      <from name="foo"/>, conjunction elimination
    </by>
  </step>
  <step name="baz">
    <derive>[...]</derive>
    <by>
      <from name="bar"/>, existential quantification
    </by>
  </step>
  [...]
</derivation>

[...]
[...]
[...]
,连词消去
[...]
存在量化
[...]
派生中的每个
都有一个数字——例如,使用
name=“foo”
将是数字
1
,使用
name=“bar”
将是数字
2
,使用
name=“baz”
将是数字
3
,等等。在
内时,我可以用
找到号码。到目前为止还不错

现在,在出现元素
的地方,我希望用
name=“bar”
元素的编号替换它。这里有三个子问题需要解决:

  • 查找
    元素的最新祖先,该元素是
  • 从中,找到第一个子元素,该子元素是具有
    name=“bar”
    元素。在上面的实例中,这将找到
    的第二个子项
  • 确定该元素的编号。在上面,这将是
    2
有人能把这些子问题的解决方案结合起来以满足我的要求吗?

XPath轴很有趣

count(ancestor::derivation/step[@name=$name]/preceding-sibling::step)+1
这将获取最近的祖先,即派生,使用正确的名称获取其子步骤,然后获取所有前面的兄弟步骤。它对它们进行计数并加1(因为第2步将有1个前面的兄弟姐妹)


这一转变

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

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="from[@name]">
  <xsl:variable name="vReferred" select=
    "ancestor::derivation[1]/step[@name = current()/@name]"/>

   <xsl:for-each select="$vReferred">
     <xsl:number count="step" level="any"/>
   </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>
<derivation>
    <step name="foo">
        <derive>[...]</derive>
        <by>[...]</by>
    </step>
    <step name="bar">
        <derive>[...]</derive>
        <by>
            <from name="foo"/>, conjunction elimination     
        </by>
    </step>
    <step name="baz">
        <derive>[...]</derive>
        <by>
            <from name="bar"/>, existential quantification     
        </by>
    </step>   [...] 
</derivation>
<derivation>
   <step name="foo">
      <derive>[...]</derive>
      <by>[...]</by>
   </step>
   <step name="bar">
      <derive>[...]</derive>
      <by>1, conjunction elimination     
        </by>
   </step>
   <step name="baz">
      <derive>[...]</derive>
      <by>2, existential quantification     
        </by>
   </step>   [...] 
</derivation>

应用于提供的XML文档时

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

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="from[@name]">
  <xsl:variable name="vReferred" select=
    "ancestor::derivation[1]/step[@name = current()/@name]"/>

   <xsl:for-each select="$vReferred">
     <xsl:number count="step" level="any"/>
   </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>
<derivation>
    <step name="foo">
        <derive>[...]</derive>
        <by>[...]</by>
    </step>
    <step name="bar">
        <derive>[...]</derive>
        <by>
            <from name="foo"/>, conjunction elimination     
        </by>
    </step>
    <step name="baz">
        <derive>[...]</derive>
        <by>
            <from name="bar"/>, existential quantification     
        </by>
    </step>   [...] 
</derivation>
<derivation>
   <step name="foo">
      <derive>[...]</derive>
      <by>[...]</by>
   </step>
   <step name="bar">
      <derive>[...]</derive>
      <by>1, conjunction elimination     
        </by>
   </step>
   <step name="baz">
      <derive>[...]</derive>
      <by>2, existential quantification     
        </by>
   </step>   [...] 
</derivation>

[...]
[...]
[...]
,连词消去
[...]
存在量化
[...] 
生成所需的正确结果

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

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="from[@name]">
  <xsl:variable name="vReferred" select=
    "ancestor::derivation[1]/step[@name = current()/@name]"/>

   <xsl:for-each select="$vReferred">
     <xsl:number count="step" level="any"/>
   </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>
<derivation>
    <step name="foo">
        <derive>[...]</derive>
        <by>[...]</by>
    </step>
    <step name="bar">
        <derive>[...]</derive>
        <by>
            <from name="foo"/>, conjunction elimination     
        </by>
    </step>
    <step name="baz">
        <derive>[...]</derive>
        <by>
            <from name="bar"/>, existential quantification     
        </by>
    </step>   [...] 
</derivation>
<derivation>
   <step name="foo">
      <derive>[...]</derive>
      <by>[...]</by>
   </step>
   <step name="bar">
      <derive>[...]</derive>
      <by>1, conjunction elimination     
        </by>
   </step>
   <step name="baz">
      <derive>[...]</derive>
      <by>2, existential quantification     
        </by>
   </step>   [...] 
</derivation>

[...]
[...]
[...]
1、连词消除
[...]
存在量化
[...] 

虽然已经发布的两个解决方案都还可以,但仅供参考,我正在添加另一个可能的解决方案

比如:

<xsl:template match="from">
  <xsl:variable name="ref" select="@name"/>
  <xsl:apply-templates mode="number" select="ancestor::derivation/step">
    <xsl:with-param name="ref" select="$ref"/>
  </xsl:apply-templates>
</xsl:template>

<xsl:template name="step" mode="number">
  <xsl:param name="ref"/>
  <xsl:if test="@name=$ref">
    Item no. <xsl:value-of select="position()"/>
  </xsl:if>
</xsl:template>

项目编号。

请注意,我已经有好几年没有编写XSLT了,虽然这个解决方案背后的想法应该是正确的,但语法可能是完全错误的。

另一个解决方案,使用键(如果对同一步骤的引用平均多于一个,可能会更有效):



请提供具有代表性的XML。提供的XML文档中没有
。太棒了。谢谢你,迪米特!XSL变量给我带来了麻烦。