如何使用XPath比较多个节点

时间:2018-05-16 21:01:25

标签: xpath xslt-1.0

鉴于下面的XML,我正在尝试编写一个仅返回此匹配的XPath:

<TOKEN BEGIN="17" END="19" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="C" DOUBLE="YES" />

这是输入文件:

<?xml version="1.0" encoding="utf-8"?>
<DOCUMENT>
  <SECTION>
    <PARAGRAPH TRACK="4">
      <SENTENCE NAME="PRIMARY" COUNT="4">
        <TOKEN BEGIN="9" END="11" SENTENCE_BEGIN="0" SENTENCE_END="156" />
        <TOKEN BEGIN="32" END="37" SENTENCE_BEGIN="0" SENTENCE_END="156" />
        <TOKEN BEGIN="167" END="169" SENTENCE_BEGIN="158" SENTENCE_END="316" />
        <TOKEN BEGIN="210" END="215" SENTENCE_BEGIN="158" SENTENCE_END="316" />
      </SENTENCE>
      <SENTENCE NAME="SECONDARY" COUNT="2">
        <TOKEN BEGIN="139" END="141" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="A" DOUBLE="YES" />
        <TOKEN BEGIN="143" END="145" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="B" />
      </SENTENCE>
      <SENTENCE NAME="SECONDARY" COUNT="1">
        <TOKEN BEGIN="17" END="19" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="C" DOUBLE="YES" />
      </SENTENCE>
    </PARAGRAPH>
  </SECTION>
</DOCUMENT>

这是我的xpath字符串:

//TOKEN [@DOUBLE] [@BEGIN <= ../../SENTENCE[@NAME='PRIMARY']/TOKEN/@END] [ (@SENTENCE_BEGIN = ../../SENTENCE[@NAME='PRIMARY']/TOKEN/@SENTENCE_BEGIN) and (@SENTENCE_END = ../../SENTENCE[@NAME='PRIMARY']/TOKEN/@SENTENCE_END) ]

我收到两个节点作为输出:

 <TOKEN BEGIN="17" END="19" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="C" DOUBLE="YES" />

<TOKEN BEGIN="139" END="141" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="A" DOUBLE="YES" />

上面的结果不正确,因为我想检查一下:

  1. SENTENCE_BEGINSENTENCE_END的{​​{1}} TOKEN[@DOULBE=YES]SENTENCE[@NAME="PRIMARY"]/TOKEN是相同的,

  2. BEGIN的属性TOKEN[@DOULBE=YES]的值小于BEGIN的{​​{1}}

  3. 结果

    SENTENCE[@NAME="PRIMARY"]/TOKEN

    不正确,因为 <TOKEN BEGIN="139" END="141" SENTENCE_BEGIN="0" SENTENCE_END="156" PROP="A" DOUBLE="YES" /> (139)大于具有相同BEGIN {{1}的令牌的相应BEGIN值值:

    SENTENCE_BEGIN

    如何修改代码行以获得所需的结果?

1 个答案:

答案 0 :(得分:0)

由于您已经标记了XSLT 1.0的问题,我使用的是XSLT而不是纯XPath。这样您就可以使用xsl:keycurrent()

示例...

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

  <xsl:key name="primary_tokens" 
    match="SENTENCE[@NAME='PRIMARY']/TOKEN" 
    use="concat(@SENTENCE_BEGIN,'|',@SENTENCE_END)"/>

  <xsl:template match="/*">
    <xsl:for-each select=".//TOKEN[@DOUBLE='YES'][key('primary_tokens',concat(@SENTENCE_BEGIN,'|',@SENTENCE_END))]">
      <xsl:if test="key('primary_tokens',concat(@SENTENCE_BEGIN,'|',@SENTENCE_END))[@BEGIN > current()/@BEGIN]">
        <xsl:copy-of select="."/>
      </xsl:if>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

小提琴:http://xsltfiddle.liberty-development.net/gWmuiJ8