Удаление пустых XML элементов после создания новых элементов - PullRequest
0 голосов
/ 27 марта 2020

Я знаю, что в Интернете есть много примеров того, как удалять пустые XML элементы с помощью XSLT, однако я не могу найти способ, который будет работать с моим документом. Я создал шаблоны, которые пишут новые элементы и хотел бы обработать окончательный шаблон, который соответствует всем элементам, у которых нет текстового содержимого внутри, включая элементы, которые являются дочерними. Если элемент содержит дочерний элемент без текста, я хотел бы удалить только пустой дочерний элемент. Я пытался использовать идентифицирующие преобразования, но они, кажется, не работают так, как я настроил свои шаблоны, но я бы хотел сохранить эту структуру.

XML

<fruitSet>
    <fruit>
        <name>apple</name>
        <colour>green</colour>
        <ratings>
            <taste>10</taste>
            <look>8</look>
        </ratings>
    </fruit>
    <fruit>
        <name>strawberry</name>
        <colour>red</colour>
        <ratings>
            <taste>7</taste>
            <look>5</look>
        </ratings>
    </fruit>    
        <fruit>
        <name>Orange</name>
        <colour></colour>
        <ratings>
            <taste>3</taste>
            <look></look>
        </ratings>
    </fruit>
</fruitSet>

XSL

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd ="http://www.w3.org/2001/XMLSchema#">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/">                
    <RDF>
        <xsl:apply-templates select = "fruitSet/fruit"/>
        <xsl:apply-templates select = "fruitSet/fruit/ratings"/>

    </RDF>
</xsl:template> 

<xsl:template match = "fruit">
    <Description>
        <xsl:attribute name = "ID">
            <xsl:value-of select = "name/text()"/>
        </xsl:attribute>
        <hasColour><xsl:value-of select = "colour/text()"/></hasColour>
        <hasTasteRating>
            <xsl:apply-templates select = "ratings"/>
        </hasTasteRating>
    </Description>
</xsl:template>


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




</xsl:stylesheet>

Желаемый выход

<?xml version="1.0" encoding="utf-16"?>
<RDF xmlns:xsd="http://www.w3.org/2001/XMLSchema#">
  <Description ID="apple">
    <hasColour>green</hasColour>
    <hasTasteRating>10</hasTasteRating>
  </Description>
  <Description ID="strawberry">
    <hasColour>red</hasColour>
    <hasTasteRating>7</hasTasteRating>
  </Description>
  <Description ID="Orange">
    <hasTasteRating>3</hasTasteRating>
  </Description>1073</RDF>
</RDF>

1 Ответ

1 голос
/ 27 марта 2020

Вы можете использовать следующую таблицу стилей XSLT-1.0. Он реализует два подхода для решения вашей проблемы:

  1. Применение xsl:if для пропуска элементов, которые вы не хотите выводить.
  2. Ограничение шаблона общего элемента предикатом

Это вся таблица стилей:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd ="http://www.w3.org/2001/XMLSchema#">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:template match="/">                
        <RDF>
            <xsl:apply-templates select = "fruitSet/fruit"/>
        </RDF>
    </xsl:template>

    <xsl:template match = "fruit">
        <Description>
            <xsl:attribute name = "ID">
                <xsl:value-of select = "name/text()"/>
            </xsl:attribute>
            <xsl:if test="normalize-space(colour)">
                <hasColour>
                    <xsl:value-of select = "colour"/>
                </hasColour>
            </xsl:if>
            <xsl:apply-templates select="ratings" />
        </Description>
    </xsl:template>

    <!-- Only create a <hasTasteRating> element for all elements with a present <taste>  child -->
    <xsl:template match="*[normalize-space(taste)]" >
        <hasTasteRating>
            <xsl:value-of select="taste/text()"/>
        </hasTasteRating>
    </xsl:template>

</xsl:stylesheet>

Его вывод:

<?xml version="1.0" encoding="UTF-8"?>
<RDF xmlns:xsd="http://www.w3.org/2001/XMLSchema#">
    <Description ID="apple">
        <hasColour>green</hasColour>
        <hasTasteRating>10</hasTasteRating>
    </Description>
    <Description ID="strawberry">
        <hasColour>red</hasColour>
        <hasTasteRating>7</hasTasteRating>
    </Description>
    <Description ID="Orange">
        <hasTasteRating>3</hasTasteRating>
    </Description>
</RDF>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...