XML-форматирование текста для XSL-преобразования - PullRequest
3 голосов
/ 11 мая 2011

Надеюсь, мой титул оправдывает вопрос. Пожалуйста, рассмотрите следующий блок XML и пример блока XSL.

<root>
<level_one>
My first line of text on level_one
<level_two>
My only line of text on level_two
</level_two>
My second line of text on level_one
</level_one>
</root>

<xsl:template match="level_one">
<xsl:value-of select="text()"/>
<br/>
<xsl:apply-templates select="level_two"/>
</xsl:template>

<xsl:template match="level_two">
<xsl:value-of select="text()"/>
<br/>
</xsl:template>

В существующем виде, выход (измененный здесь для чтения) при выполнении вышеупомянутого равен

My first line of text on level_one
<br/>
My only line of text on level_two
<br/>

Мне не хватает второй строки текста на level_one. Поэтому мне интересно две вещи.

  1. Действителен ли XML? Насколько я знаю, ответ - да, но я не прав?
  2. Как я могу изменить XSL, чтобы получить вторую строку (или даже больше строк в моем случае, чем я показал)?

Спасибо

Ответы [ 3 ]

1 голос
/ 12 мая 2011

Используйте стандартную модель обработки рекурсивного спуска XSLT с использованием xsl: apply-templates.

<xsl:template match="*">
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="text()">
<xsl:value-of select="."/>
<br/>
</xsl:template>

Использование <xsl:value-of select="text()"/> - плохая новость. В XSLT 1.0 он отображает только первый текстовый узел (как вы обнаружили). В XSLT 2.0 он отображает все дочерние текстовые узлы, разделенные пробелами, но, вероятно, это не то, что вам нужно, потому что он выведет первое и третье предложения до второго. (На самом деле вы не сказали точно, какой вывод вы хотите, поэтому я должен догадаться.)

1 голос
/ 12 мая 2011

Даже если шаблон не соответствует text(), вы можете вывести двух text() дочерних узлов текущего узла (level_one) на , заменив :

<xsl:value-of select="text()"/>

с :

<xsl:copy-of select="text()"/>

В XSLT 1.0 очень важно знать, что <xsl:value-of select="$someNodeSet"/> создает строковое значение только первого узла (в порядке документа) из $someNodeSet набора узлов.

С другой стороны :

<xsl:copy-of select="$someNodeSet"/>

копирует все узлы, содержащиеся в $someNodeSet.

0 голосов
/ 11 мая 2011

Действителен ли XML? Из того, что я знаю, ответ да, но я не прав?

Да, ваш XML действителен. Кроме того, вопреки комментарию выше, нет ничего плохого в том, что в XML смешано содержимое (текст и элементы смешаны) Все зависит от контекста и того, как используется XML. Например, было бы почти невозможно создать технические руководства без смешанного контента. (Хорошим примером являются ссылочные элементы, смешанные с текстом в элементах абзаца.)

Как я могу изменить XSL, чтобы получить вторую строку (или даже больше линий в моем случае, чем я показал)?

Я не совсем уверен, чего именно вы пытаетесь достичь, но причина, по которой вы не видите вторую строку текста, заключается в том, что вы сопоставляете только первую строку с первой <xsl:value-of select="text()"/>.

Я не уверен, что это сработает на вашем полном наборе данных XML, но вы можете заменить оба шаблона level_one и level_two на один шаблон, который соответствует всем text():

  <xsl:template match="text()">
    <xsl:value-of select="."/>
    <br/>
  </xsl:template>

Это дает следующий вывод:

  My first line of text on level_one
  <br/>
  My only line of text on level_two
  <br/>
  My second line of text on level_one
  <br/>

Вы также можете сузить соответствие, указав level_one и level_two родителей:

  <xsl:template match="level_one/text()|level_two/text()">
    <xsl:value-of select="."/>
    <br/>
  </xsl:template>

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

Надеюсь, это поможет.

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