Мне организовали XML как ниже -
<section name="Parent 1 Text here" ID="1" >
<section name="Child 1 Text here" ID="11">
</section>
<section name="Child 2 Text here" ID="12">
<section name="GrandChild Text here" ID="121" >
</section>
</section>
</section>
<section name="Parent 2 Text here" ID="2" >
<section name="Child 1 Text here" ID="22">
</section>
<section name="Child 2 Text here" ID="23">
<section name="GrandChild Text here" ID="232" >
</section>
</section>
</section>
Я должен произвести ниже вывода XML -
<section name="Parent 1 Text here" ID="1" >
<section name="Child 2 Text here" ID="12">
<section name="GrandChild Text here" ID="121" >
</section>
</section>
</section>
<section name="Parent 2 Text here" ID="2" >
<section name="Child 2 Text here" ID="23">
</section>
</section>
Я имею к achive выше использования преобразования XSLT 1.0. Я планировал передать разделенную строку запятой в качестве параметра со значением = "1,12,121,2,23"
Мой вопрос - Как циклично выполнить запятую, разделил параметр в XSLT 1.0? Есть ли более простой способ достигнуть вышеупомянутого. Помните, что я должен сделать это в XSLT 1.0, Ваша справка ценится.
Вот альтернатива подходу Яна Виллема Б. Я не утверждаю, что это лучше или хуже. Я представляю его по двум причинам:
Возможно, вы захотите увидеть, как будет выглядеть рекурсивный подход
Он ведет себя по-разному для некоторых входных данных (хотя он ведет себя так же для данных вашего примера). В частности, если ваш фильтр включает два узла, которые являются потомками одного и того же узла, эта таблица стилей выведет две вложенные структуры данных, каждая с одним листовым узлом, в то время как ответ Яна Виллема B выведет одну вложенную структуру с двумя листовыми узлами. Не знаю, что тебе нужно.
Для моей таблицы стилей вы должны передать фильтр, перечисляющий только те листовые узлы, которые вам нужны. Он найдет своих предков. Для этого я предположил, что ваш корневой узел называется
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:param name="descendant-ids" select="'121,23'"/>
<xsl:template match="/">
<doc>
<xsl:call-template name="recurse-ids">
<xsl:with-param name="ids" select="concat($descendant-ids,',')"/>
</xsl:call-template>
</doc>
</xsl:template>
<xsl:template name="recurse-ids">
<xsl:param name="ids"/>
<xsl:variable name="id" select="substring-before($ids,',')"/>
<xsl:variable name="remaining-ids" select="substring-after($ids,',')"/>
<xsl:apply-templates select="/doc/section">
<xsl:with-param name="id" select="$id"/>
</xsl:apply-templates>
<xsl:if test="$remaining-ids">
<xsl:call-template name="recurse-ids">
<xsl:with-param name="ids" select="$remaining-ids"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="section">
<xsl:param name="id"/>
<xsl:if test="starts-with($id,@ID)">
<xsl:copy>
<xsl:apply-templates select="@*|node()">
<xsl:with-param name="id" select="$id"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:if>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Рекурсия не обязательно является решением. В принципе, ваша строка с запятыми может быть применена как фильтр:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="filter">1,12,121,2,23</xsl:param>
<xsl:template match="section">
<xsl:if test="contains(concat(',', $filter, ','), concat(',', @ID, ','))">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
<!-- copy the rest -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>