Преобразование XML к простому тексту - как я должен игнорировать/обрабатывать пробел в XSLT?

Как будто вы пытаетесь получить доступ к объекту, который является null. Рассмотрим ниже пример:

TypeA objA;

. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException, что имеет смысл.

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
36
задан Mathias Müller 21 March 2014 в 16:13
поделиться

3 ответа

Существует три причины получения нежелательного пробела в результате преобразования XSLT:

  1. пробел, который прибывает из-за узлов в пробел исходного документа
  2. , который прибывает из узлов в пробел исходного документа
  3. , который прибывает из таблицы стилей

, я собираюсь говорить обо всех трех, потому что может быть трудно сказать, куда пробел прибывает из того, таким образом, Вы, возможно, должны были бы использовать несколько стратегий.

Для обращения к пробелу, который является между узлами в исходном документе необходимо использовать <xsl:strip-space> для разделения любого пробела, который появляется между двумя узлами, и затем используйте <xsl:preserve-space> для сохранения значительного пробела, который мог бы появиться в смешанном содержании. Например, если Ваш исходный документ похож:

<ul>
  <li>This is an <strong>important</strong> <em>point</em></li>
</ul>

тогда Вы захотите проигнорировать пробел между <ul> и <li> и между </li> и эти </ul>, который не является значительным, но сохраните пробел между <strong> и <em> элементы, который является значительный (иначе, Вы добрались бы, "Это ** важная точка ****"). Чтобы сделать это использование

<xsl:strip-space elements="*" />
<xsl:preserve-space elements="li" />

Эти elements, атрибут на [1 115] должен в основном перечислить все элементы в Вашем документе, которые смешали содержание.

В стороне: использование <xsl:strip-space> также уменьшает размер исходного дерева в памяти и делает Вашу таблицу стилей более эффективной, таким образом, это стоит сделать, даже если у Вас нет пробельных проблем этого вида.

Для обращения к пробелу, который появляется в узлах в исходном документе необходимо использовать normalize-space(). Например, если Вы имеете:

<dt>
  a definition
</dt>

и можно быть уверены, что <dt> элемент не будет содержать элементов, с которыми Вы хотите сделать что-то, тогда можно сделать:

<xsl:template match="dt">
  ...
  <xsl:value-of select="normalize-space(.)" />
  ...
</xsl:template>

продвижение и запаздывающий пробел будут разделены от значения <dt> элемент, и Вы просто получите строку "a definition".

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

<xsl:template match="name">
  Name:
  <xsl:value-of select="." />
</xsl:template>

таблицы стилей XSLT анализируются таким же образом как исходные документы, которые они обрабатывают, таким образом, вышеупомянутое, XSLT интерпретируется как дерево, которое содержит <xsl:template> элемент с match атрибут, первый ребенок которого является текстовым узлом и чей второй ребенок <xsl:value-of> элемент с select атрибут. Текстовый узел имеет ведущий и запаздывающий пробел (включая разрывы строки); так как это - буквенный текст в таблице стилей, это буквально копируется в результат со всем продвижением и запаздывающим пробелом.

, Но [приблизительно 1 131] пробел в таблицах стилей XSLT разделяется автоматически, а именно, те между узлами. Вы не получаете разрыв строки в своем результате, потому что существует разрыв строки между <xsl:value-of> и завершение <xsl:template>.

Для получения только текста Вы хотите в результате, используете <xsl:text> элемент как это:

<xsl:template match="name">
  <xsl:text>Name: </xsl:text>
  <xsl:value-of select="." />
</xsl:template>

процессор XSLT проигнорирует разрывы строки и добавление отступа, которые появляются между узлами, и только производят текст в <xsl:text> элемент.

77
ответ дан JeniT 27 November 2019 в 05:33
поделиться

Вы используете отступ = "нет" в Вашем выходном теге?

<xsl:output method="text" indent="no" />

Также, если Вы используете xsl:value, можно использовать disable-output-escaping = "да" для помощи с некоторыми пробельными проблемами.

4
ответ дан Lindsay 27 November 2019 в 05:33
поделиться

Относительно Вашего редактирования о новых строках можно использовать этот шаблон для рекурсивной замены одной строки в другой строке, и можно использовать его для разрывов строки:

<xsl:template name="replace.string.section">
  <xsl:param name="in.string"/>
  <xsl:param name="in.characters"/>
  <xsl:param name="out.characters"/>
  <xsl:choose>
    <xsl:when test="contains($in.string,$in.characters)">
      <xsl:value-of select="concat(substring-before($in.string,$in.characters),$out.characters)"/>
      <xsl:call-template name="replace.string.section">
        <xsl:with-param name="in.string" select="substring-after($in.string,$in.characters)"/>
        <xsl:with-param name="in.characters" select="$in.characters"/>
        <xsl:with-param name="out.characters" select="$out.characters"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$in.string"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template> 

Вызов это следующим образом (этот пример заменяет разрывы строки в переменной $some.string с пространством):

    <xsl:call-template name="replace.string.section">
        <xsl:with-param name="in.string" select="$some.string"/>
        <xsl:with-param name="in.characters" select="'&#xA;'"/>
        <xsl:with-param name="out.characters" select="' '"/>
    </xsl:call-template>
0
ответ дан Odilon Redo 27 November 2019 в 05:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: