XML: проверьте, существует ли что-либо между двумя узлами - PullRequest
3 голосов
/ 25 марта 2010

Мне нужно выяснить, существует ли что-нибудь между двумя узлами. Мой XML выглядит так:

<event value1="1" value2="2" value3="3" info="some info here">
          Line 1.<lb/>
          Line 2.<lb/><lb/>
          Line 3.<lb/>
          Line 4.<lb/>
</event>

Моя цель - преобразовать узлы <lb/> в <br/> теги HTML с помощью XSLT. Есть одно дополнительное требование, чтобы выполнить все же. Если есть один <lb/> непосредственно , следующий за другим <lb/>, я хочу вывести только один <br/>.

Мой XSLT выглядит так:

 <xsl:template match="lb">
    <xsl:if test="not(preceding-sibling::lb[1])">
       <br/>
    </xsl:if>
 </xsl:template>

Проблема с XSLT выше заключается в том, что он работает правильно только для строки 1, поскольку текст между обоими узлами игнорируется.

Может быть, кто-то здесь может помочь.

Ответы [ 3 ]

3 голосов
/ 26 марта 2010

Вы ищете что-то вроде этого:

<!-- per default, <lb> gets removed (empty template)... -->
<xsl:template match="lb" />

<!-- ...unless it is directly preceded by a non-blank text node -->
<xsl:template match="lb[
  normalize-space(preceding-sibling::node()[1][self::text()]) != ''
]">
  <br />
</xsl:template>

Это обрабатывает любое произвольное количество <lb/> узлов, которые могут возникать последовательно.

Поведение для <lb/> узлов, которые следуют за элементом (не текстовым узлом), все еще должно быть определено. В настоящее время они будут удалены. Если вы хотите сохранить их, напишите соответствующий шаблон для них.

3 голосов
/ 25 марта 2010

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

<xsl:template match="lb">
    <xsl:if test="following-sibling::node()[1][not(self::lb)]">
        <br/>
    </xsl:if>
</xsl:template>

Попробуйте:

 <xsl:template match="lb">
   <xsl:if test="generate-id()=generate-id(preceding-sibling::text()[1]/following-sibling::lb[1])">
     <br/>
   </xsl:if>
 </xsl:template>

В основном это проверяет, если вы включеныпервый <lb/> предыдущий узел-родственный текст, что также означает, что он будет добавлять <br/> только после некоторого текста, но не в том случае, если <lb/> находится в начале родительского тега.

1 голос
/ 26 марта 2010

Это преобразование :

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

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

 <xsl:template match="lb"/>

 <xsl:template match=
  "lb[not(following-sibling::node()[1][self::lb])]">
  <br />
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному документу XML :

<event value1="1" value2="2" value3="3" info="some info here">
          Line 1.<lb/>
          Line 2.<lb/><lb/>
          Line 3.<lb/>
          Line 4.<lb/>
</event>

дает желаемый результат :

<event value1="1" value2="2" value3="3" info="some info here">
          Line 1.<br/>
          Line 2.<br/>
          Line 3.<br/>
          Line 4.<br/>
</event>

Примечание :

  1. Использование и переопределение тождественного преобразования .

  2. Как <lb> элементы удаляются по умолчанию.

  3. Как только последний элемент <lb> в группе соседних узлов <lb> обрабатывается особым образом - заменяется элементом <br />.

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