Я новичок в XSLT и теперь у меня есть довольно сложная проблема ... Мой входной файл выглядитНаилучшая практика для вставки и удаления элементов с помощью XSLT
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<doc>
<outerElement>
<first>
<textElement>Some Text</textElement>
</first>
<second>
<textElement>Some Text</textElement>
</second>
<third>
<textElement>Some Text</textElement>
</third>
</outerElement>
</doc>
Проблема возникает с «вторым» элементом. Во входном файле он может иметь одну из трех форм:
MISSING
<second>
<textElement>Some Text</textElement>
</second>
<second missingCause="" />
В выходном файле он должен быть вставлен как вторая форма. Если он отсутствовал до того, как textElement должен указать, что он был вставлен шаблоном, и что важно здесь, он должен быть на второй позиции, потому что я хочу проверить его на схеме xsd ...
Вот мой текущий XSL :
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- COPY ALL ELEMENTS -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- remove Elements with attribute deleteme -->
<xsl:template match="outerElement/second[@missingCause='*']" />
<!-- look if second is there. If not insert -->
<xsl:template match="outerElement">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
<xsl:if test="not(second)">
<second>
</second>
</xsl:if>
</xsl:copy>
</xsl:template>
<!-- Insert Element second -->
<xsl:template match="outerElement/second">
<xsl:apply-templates select="node()|@*"/>
<xsl:copy>
<xsl:if test="not(textElement)">
<textElement>Inserted by Template</textElement>
</xsl:if>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Если «второй» отсутствует мой выходной файл просто получает элемент «», но его пустым и последнее преобразование не будет применена. Все остальное выглядит хорошо, когда у меня в Документе я получаю предупреждение ...
Может кто-то, пожалуйста, помогите мне переместить элемент туда, где он должен быть, поэтому он проверяет схему и заставляет ее работать во всех трех случаи?
Я думаю, что мой способ кажется не очень хорошим и закончится хаотичным, потому что у меня есть несколько похожих элементов для вставки/удаления, как это.
Спасибо за чтение;)
Эй, спасибо за ваш ответ, похоже, это то, что мне нужно сделать, но я не понимаю, как он работает во всех аспектах. Первый шаблон - это шаблон идентификации, который одобрен. Второй, похоже, делает некоторые сумасшедшие вещи, которые он устанавливает, что режим отсутствует, поэтому четвертый шаблон вставляет элемент, а третий удаляет объект с отсутствием причины?- Как работает первый и почему существует переменная? –
@DennisIch: Это называется * многопроходной обработкой *. Основная идея заключается в том, что вывод каждого прохода фиксируется в переменной xsl: а затем в следующем проходе шаблоны применяются к дереву, содержащемуся в этой переменной. Я предполагаю, что вас смущает использование функции расширения ext: node-set() - это необходимо в XSLT 1.0 (не требуется в XSLT 2.0) из-за ограничений (печально известного типа RTF) XSLT 1.0 , См. Например, этот ответ: http://stackoverflow.com/a/6529617/36305 –
ОК, чтобы уточнить ... Этот шаблон, в котором переменная находится в самой переменной, не производит никакого вывода, а обрабатывается, и он копирует личность и тогда? Этот второй выбор запускает «отсутствующий» шаблон? Я смущен тем, как он перескакивает из шаблона в шаблон; (- Не было бы проще/яснее, если я буду хранить OuterElement в переменной и использовать xsl: call-template на нем? Тогда я мог бы создать несколько недостающих переменных. –