XSLT - Удалить узлы, когда текущий узел равен предыдущему узлу. - PullRequest
0 голосов
/ 30 мая 2018

Мне нужно написать XSLT для xml, который содержит формат ниже.

<books>
<book>
 <a>name</a>
 <a>name</a>
 <b>name</b>
 <b>name</b>
</book>
</books>

Мне нужно удалить дубликаты дочерних узлов в некоторых условиях.

  1. Только если (текущий узел == предыдущий узел), то его следует удалить.

то есть .. если предыдущий узел (элемент) равен <a>, а текущий узел (элемент) также равен <a>, то один узелдолжен быть удален.

вывод для вышеупомянутого:

`<a>name</a>`

`<b>name</b>`

, пожалуйста, помогите мне сделать это.

Ответы [ 2 ]

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

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

  • также является листомэлемент ,
  • имеет то же имя ,
  • имеет одинаковое текстовое содержимое .

Итакнаиболее интуитивное решение (я думаю) - написать пустой шаблон, соответствующий только этим узлам:

<xsl:template match="*[not(*)][preceding-sibling::*[1][not(*)]
  [name() = current()/name()][text() = current()/text()]]"/>

Краткое описание атрибута соответствия:

  • *[not(*)] -Каждый элемент без дочернего элемента (листовой элемент).
  • [ - Начало второго предиката.
    • preceding-sibling::*[1] - Возьмите первого предшествующего брата.
    • [not(*)] - У него не должно быть дочерних элементов.
    • [name() = current()/name()] - У него должно быть то же имякак «начальный» элемент.
    • [text() = current()/text()] - должен иметь тот же текст, что и «начальный» элемент.
  • ] - Конец второго предиката.

Конечно, сценарий должен также содержать шаблон идентификации .

Рабочий пример с немного расширенным источником см. http://xsltransform.net/jxN8Nqm

Если требование в отношении того же текста не требуется, удалите соответствующий фрагмент предиката.

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

В XSLT 2 или 3 вы можете легко сгруппировать соседние элементы-братья по имени их узла с for-each-group select="*" group-adjacent="node-name()" и просто вывести первый элемент в каждой группе (который равен элементу контекста .):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="book">
      <xsl:copy>
          <xsl:for-each-group select="*" group-adjacent="node-name()">
              <xsl:copy-of select="."/>
          </xsl:for-each-group>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty -development.net / 6qVRKw4 / 1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...