Как проверить, имеет ли хотя бы один потомок узла текстовое содержимое? - PullRequest
1 голос
/ 07 июля 2019

У меня есть XML, который выглядит как

<xml>
    <grandparent>
        <parent>
            <child1/>
            <child2/>
            <child3>value</child3>
        </parent>
    </grandparent>
</xml>

Мне нужно применить определенный шаблон, если хотя бы один потомок родителя имеет значение

После поиска на этом сайте я нашел код

<xsl:if test="grandparent/parent//* != '' ">
    <xsl:apply-templates select="parent"/>
</xsl:if>

Но это не работает.Ничего не происходит, когда я запускаю это.Сам по себе apply-template работает, поэтому проблема не в шаблоне. Что я делаю не так?

1 Ответ

1 голос
/ 07 июля 2019

Мне нужно применить определенный шаблон, если хотя бы один потомок родителя имеет значение

После поиска по этому сайту я нашел код

<xsl:if test="grandparent/parent//* != '' ">
    <xsl:apply-templates select="template1"/>
</xsl:if>

Но он не работает.

Анализ :

  1. Когда шаблоны применяются с помощью инструкции <xsl:apply-templates>, нельзя указать любое имя шаблона (а шаблоны обычно не являютсяимя).Ожидается, что атрибут select будет содержать выражение XPath, возвращающее набор узлов (последовательность в XSLT 3.0) с узлами, к которым должны применяться шаблоны.
  2. Следовательно, select="template1" означает не применять шаблон с именем "template1", но применять шаблоны к любому дочернему элементу текущего узла с именем template1 Поскольку в предоставленном XML-документе нет элементов с именем template1, ничего не выбрано и ничего неПрименяемые шаблоны включены.Это объясняет сообщаемое поведение

Возможно, вы захотите использовать <xsl:call-template name="template1">, но вызов именованных шаблонов обычно не рекомендуется в XSLT.

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

Решение :

Предположим, что текущий узел является верхним узлом в документе XML.

Ниже приведено преобразование, которое все еще использует <xsl:apply-templates>, но задает только режим шаблона, который будет использоваться процессором XSLT при выборе шаблона для выполнения:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <xsl:template match="grandparent">
    <xsl:apply-templates mode="template1" select="parent[*//text()]"/>
  </xsl:template>

  <xsl:template match="parent" mode="template1">
    Template in mode template1 Applied
  </xsl:template>
</xsl:stylesheet>

Когда это преобразование применяется к предоставленному XMLдокумент:

<xml>
    <grandparent>
        <parent>
            <child1/>
            <child2/>
            <child3>value</child3>
        </parent>
    </grandparent>
</xml>

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

Template in mode template1 Applied

Теперь давайте проверим это с измененным документом XML, в котором нет дочерних элементовgrandparent/parent имеет дочерний текстовый узел:

<xml>
    <grandparent>
        <parent>
            <child1/>
            <child2/>
            <child3></child3>
        </parent>
    </grandparent>
</xml>

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

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