Как проверить, является ли предок последним элементом этого типа в его предке - PullRequest
2 голосов
/ 22 декабря 2011

У меня есть следующий XML:

<TABLE>
  <ROW>
    <ENTRY/>
    <ENTRY/>
  </ROW>
  <ROW>
    <ENTRY>xxx</ENTRY>
    <ENTRY>yyy</ENTRY>
  </ROW>
  <Z>
    <ROW>
      <ENTRY/>
      <ENTRY/>
    </ROW>
  </Z>
  <ROW>
    <ENTRY/>
    <ENTRY/>
  </ROW>
</TABLE>

Структура таблицы может измениться, поэтому я могу заключить последнюю строку в элемент Z или не может быть элемента Z вообще.

Моя цель - убрать нижнюю границу в записях последней строки таблицы.(ТАБЛИЦА сопоставляется с таблицей HTML, ROW с HTML tr, ENTRY to HTML td)

, поэтому я пытаюсь использовать шаблон xslt:

<xsl:template match="ENTRY">
  <td>
    <xsl:if test="(ancestor::ROW[1] = ancestor::TABLE[1]/descendant::ROW[last()])">
      <!-- remove the bottom border of td -->
    </xsl:if>  
  </td>
</xsl:template>

Но он удаляет границу почти из всех ячеекв таблице (граница не удаляется из ячеек с текстовым содержимым).Поэтому я предполагаю, что механизм проверяет, имеют ли узлы одинаковое значение (имя, текстовое содержимое, дочерние элементы и т. Д.), А не ссылки.Я пытался использовать некоторые внешние функции в Java, но я всегда получаю новую ссылку на узел (даже для тех же узлов), поэтому я не могу сравнить его.

Так что мой вопрос - как сравнитьссылки на узлы ... или выполнить работу любым другим способом.

Заранее спасибо:).

Ответы [ 2 ]

4 голосов
/ 22 декабря 2011

Моя цель - убрать нижнюю границу в записях последней строки таблицы.(ТАБЛИЦА сопоставляет с таблицей HTML, ROW с HTML tr, ENTRY to HTML td)

Кажется, что вы хотите :

<xsl:if test=
  "generate-id(ancestor::ROW[1]) 
  = 
   generate-id(ancestor::TABLE[1]/descendant::ROW[last()])">

  <!-- Processing here -->
</xsl:if>

Я рекомендую вам добавить новый шаблон и использовать сопоставление с шаблоном (вместо явного условия), чтобы зафиксировать этот случай:

<xsl:template match=
"ENTRY[generate-id(ancestor::ROW[1]) 
      = 
       generate-id(ancestor::TABLE[1]/descendant::ROW[last()])
      ]">

      <!-- Processing here -->
</xsl:template>

Ваш более общий вопрос:

Итаку меня вопрос - как сравнить ссылки узлов

В XPath 2.0 (XSLT 2.0) используйте оператор is :

$n1 is $n2

проверяет два узла $n1 и $n2 на идентичность узла (не равенство значений).

В XPath 1.0 (XSLT 1.0):

count($n1|$n2) = 1

Другим способом в XSLT 1.0 является использование стандартной функции XSLT 1.0 (недоступно в XPath 1.0) generate-id(), как это сделано ввышеуказанное решение:

generate-id($n1) = generate-id($n2)
0 голосов
/ 22 декабря 2011

Ваш тест (ancestor::ROW[1] = ancestor::TABELA[1]/descendant::ROW[last()]) соответствует первым двум и последним двум ENTRY элементам в вашем образце.Предположительно, потому что при отображении в виде строк первый ROW совпадает с последним ROW.См. http://www.w3.org/TR/xpath/#booleans

Мне удалось выбрать две последние записи, используя:

//ENTRY[count(ancestor::ROW[1]/preceding::ROW) = count(ancestor::TABLE[1]/descendant::ROW) - 1]

Так что я думаю, что следующий тест будет работать как ваш тест:

(count(ancestor::ROW[1]/preceding::ROW) = count(ancestor::TABLE[1]/descendant::ROW) - 1)

Обновление Предоставлено отзывами Дмитрия Новатчева и Яссо

Это решение не идеально, так как:

  1. Эти подсчетынеэффективно, считая больше вещей, чем необходимо. Ось
  2. preceding:: может соответствовать больше, чем просто потомки элемента TABLE, когда он является частью более крупного документа.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...