Как сравнить несколько узлов с XPath - PullRequest
0 голосов
/ 17 мая 2018

Учитывая приведенный ниже 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_BEGIN SENTENCE_END, значения TOKEN[@DOULBE=YES] и SENTENCE[@NAME="PRIMARY"]/TOKEN одинаковы, а

  2. значение атрибута BEGIN из TOKEN[@DOULBE=YES] меньше BEGIN из SENTENCE[@NAME="PRIMARY"]/TOKEN

Результат

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

неверно, так как значение BEGIN (139) больше соответствующих BEGIN значений токенов с такими же значениями SENTENCE_BEGIN SENTENCE_END:

<TOKEN BEGIN="9" END="11" SENTENCE_BEGIN="0" SENTENCE_END="156" />
<TOKEN BEGIN="32" END="37" SENTENCE_BEGIN="0" SENTENCE_END="156" />

Как мне изменить строку кода, чтобы получить желаемый результат?

1 Ответ

0 голосов
/ 17 мая 2018

Поскольку вы отметили свой вопрос XSLT 1.0, я бы использовал XSLT вместо чистого XPath. Таким образом, вы можете использовать xsl: key , а также current () .

Пример ...

<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>

Fiddle: http://xsltfiddle.liberty -development.net / gWmuiJ8

...