XSLT для выбора нужных элементов при вложении в нежелательные элементы - PullRequest
0 голосов
/ 18 июня 2009

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

Рассмотрим:

<alpha_top>This prints.
  <beta>This doesn't.
    <alpha_bottom>This too prints.</alpha_bottom>
  </beta>
</alpha_top>

Я хочу преобразование, которое производит:

<alpha_top>This prints.
    <alpha_bottom>This too prints.</alpha_bottom>
</alpha_top>

Этот ответ показывает, как выбирать узлы на основе наличия строки в имени тега элемента.

Ответы [ 4 ]

0 голосов
/ 18 июня 2009

Вероятно, самое простое решение вашей проблемы это:

<xsl:template match="alpha_top|alpha_bottom">
  <xsl:copy>
    <xsl:value-of select="text()" />
    <xsl:apply-templates />
  </xsl:copy>
</xs:template>

<xsl:template match="text()" />

Это не демонстрирует такое же поведение пробелов, как в вашем примере, но это, вероятно, не имеет значения.

0 голосов
/ 18 июня 2009

Хорошо, вот лучший способ

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

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

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

</xsl:stylesheet>

Это в основном делает преобразование идентичности, но для элемента, который вы не хотите включать, я удалил xsl: copy и применил только шаблоны к дочерним элементам.

0 голосов
/ 18 июня 2009

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

У вас есть несколько вариантов, как это сделать. Ответ Даррелла Миллера показывает, что вам нужно обработать весь документ и выделить элементы, которые вам не интересны. Это один из подходов.

Прежде чем идти дальше, у меня создается впечатление, что вы можете не совсем «понять» концепцию контекста в XSLT. Это важно и сделает вашу жизнь проще. В любое время в XSLT есть один и единственный узел контекста. Это узел (элемент, атрибут, комментарий и т. Д.), Который в данный момент «обрабатывается». Внутри шаблона, вызываемого через xsl: select, выбранный узел является контекстным узлом. Итак, учитывая ваш xml:

<alpha_top>This prints.
  <beta>This doesn't.
    <alpha_bottom>This too prints.</alpha_bottom>
  </beta>
</alpha_top>

и следующее:

<xsl:apply-templates select='beta'/>

и

<xsl:template match='beta'>...</xsl:template>

бета-узел будет контекстным узлом внутри шаблона. Это немного больше, чем это, но не так много.

Итак, когда вы начинаете свою таблицу стилей с чего-то вроде:

<xsl:template match='/'>
    <xsl:apply-templates select='alpha_top'/>
</xsl:apply-templates>

вы выбираете дочерние элементы узла документа (единственным дочерним элементом является элемент alpha_top). Ваш оператор xpath внутри относится к контекстному узлу.

Теперь в этом шаблоне верхнего уровня вы можете решить, что хотите обрабатывать только ваши узлы alpha_bottom. Тогда вы могли бы сделать заявление вроде:

<xsl:template match='/>
    <xsl:apply-templates select='//alpha_top'/>
</xsl:template>

Это будет идти по дереву и выбирать все элементы alpha_top и ничего больше.

В качестве альтернативы вы можете обработать все свои элементы и просто игнорировать содержимое бета-узла:

<xsl:template match='beta'>
    <xsl:apply-templates/>
</xsl:template>

(как я уже говорил в моем другом ответе xsl: apply-templates без атрибута select - то же самое, что и использование select = '' *).

Это будет игнорировать содержимое бета-узла, но обрабатывать все его дочерние элементы (при условии, что у вас есть шаблоны).

Итак, игнорирование элементов в ваших выходных данных в основном заключается в использовании правильных операторов xpath в ваших атрибутах select. Конечно, вы можете захотеть хороший учебник по xpath:)

0 голосов
/ 18 июня 2009

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

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
    <xsl:apply-templates select="alpha_top"></xsl:apply-templates>
</xsl:template>

<xsl:template match="alpha_top">
    <xsl:copy>
    <xsl:apply-templates select="beta/alpha_bottom|text()"></xsl:apply-templates>
    </xsl:copy>
</xsl:template>

<xsl:template match="*|text()">
    <xsl:copy>
        <xsl:apply-templates select="*|text()"></xsl:apply-templates>
    </xsl:copy>
</xsl:template>
</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...