XSLT 1.0 - избыточные теги после применения преобразования - PullRequest
0 голосов
/ 22 марта 2019

У меня есть образец XML-файла, как показано ниже;

<ItemList>
  <Item>
    <Name>1</Name>
    <Lon>66.406180329538</Lon>
    <Lat>35.7185924672465</Lat>

  </Item>
  <Item>
    <Name>2</Name>
    <cx>1</cx>
    <cy>2</cy>
    <rx>3</rx>
    <ry>4</ry>
  </Item>
</ItemList> 

Я хочу создать файл xslt, который обрабатывает, если у Item есть узел "Lon", то он должен создавать объект Point, если у элемента есть узел "cx", он должен создавать объект "Circle".

Для этого я создал файл xslt, как показано ниже;

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
        <xsl:variable name="var1_initial" select="."/>
        <ItemList xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xal="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0">
            <xsl:attribute name="xsi:noNamespaceSchemaLocation" namespace="http://www.w3.org/2001/XMLSchema-instance"></xsl:attribute>
            <xsl:for-each select="ItemList/Item">
                <xsl:variable name="var2_cur" select="."/>
                <Item>
                    <CommonMetadata>
                        <xsl:for-each select="Name">
                            <xsl:variable name="var3_cur" select="."/>
                            <Description>
                                <xsl:value-of select="."/>
                            </Description>
                        </xsl:for-each>

                        <Geography>
                            <KMLRepresentation>
                                <kml:kml>
                                    <kml:Folder>
                                        <kml:Placemark>

                                           <kml:Circle>
                                                <xsl:for-each select="cx">
                                                    <xsl:variable name="var4_cur" select="."/>
                                                    <xsl:attribute name="cx">
                                                        <xsl:value-of select="number(.)"/>
                                                    </xsl:attribute>
                                                </xsl:for-each>
                                                <xsl:for-each select="cy">
                                                    <xsl:variable name="var5_cur" select="."/>
                                                    <xsl:attribute name="cy">
                                                        <xsl:value-of select="number(.)"/>
                                                    </xsl:attribute>
                                                </xsl:for-each>
                                                <xsl:for-each select="rx">
                                                    <xsl:variable name="var6_cur" select="."/>
                                                    <xsl:attribute name="r">
                                                        <xsl:value-of select="number(.)"/>
                                                    </xsl:attribute>
                                                </xsl:for-each>
                                            </kml:Circle>


                                          <kml:Point>
                                                <xsl:for-each select="Lon">
                                                    <xsl:variable name="var7_cur" select="."/>
                                                    <xsl:for-each select="$var2_cur/Lat">
                                                        <xsl:variable name="var8_cur" select="."/>
                                                        <kml:coordinates>
                                                            <xsl:value-of select="concat($var7_cur, ',', .)"/>
                                                        </kml:coordinates>
                                                    </xsl:for-each>
                                                </xsl:for-each>
                                            </kml:Point>

                              </kml:Placemark>
                                    </kml:Folder>
                                </kml:kml>
                            </KMLRepresentation>
                        </Geography>
                    </CommonMetadata>
                </Item>
            </xsl:for-each>
        </ItemList>
    </xsl:template>
</xsl:stylesheet>

Но после применения этого xslt-файла появляются пустые теги, такие как <kml:Point/> в объекте Circle и <kml:Circle/> в объекте Point. Я не делаю эти лишние теги. Если у элемента есть узел "cx", у преобразованного объекта Circle не должно быть пустого тега.

Это мой пример вывода;

<?xml version="1.0" encoding="UTF-8"?>
<ItemList>
    <Item>
        <CommonMetadata>
            <Description>1</Description>

            <Geography>
                <KMLRepresentation>
                    <kml:kml>
                        <kml:Folder>
                            <kml:Placemark>
                                <kml:Circle/>
                                <kml:Point>
                                    <kml:coordinates>66.406180329538,35.7185924672465</kml:coordinates>
                                </kml:Point>
                            </kml:Placemark>
                        </kml:Folder>
                    </kml:kml>
                </KMLRepresentation>
            </Geography>    
        </CommonMetadata>
    </Item>
    <Item>
        <CommonMetadata>
            <Description>2</Description>            
            <Geography>
                <KMLRepresentation>
                    <kml:kml>
                        <kml:Folder>
                            <kml:Placemark>
                                <kml:Circle cx="1" cy="2" r="3"/>
                                <kml:Point/>
                            </kml:Placemark>
                        </kml:Folder>
                    </kml:kml>
                </KMLRepresentation>
            </Geography>

        </CommonMetadata>
    </Item>
</ItemList>

Я попробовал функции xsl:if test и xsl:when test, но не смог справиться с этим снова. Не могли бы вы помочь по моей проблеме?

1 Ответ

1 голос
/ 22 марта 2019

В контексте <xsl:for-each select="ItemList/Item"> у вас есть элементы <kml:Circle> и <kml:Point>, которые создаются на каждой итерации for-each. Если вы хотите сгенерировать <kml:Circle> только для <Item> элементов, которые имеют <cx> дочерних элементов, вам необходимо соответствующим образом реструктурировать свой код.

В качестве подсказки в элементе <kml:Placemark> не просто создайте элементы <kml:Circle> и <kml:Point> по умолчанию - добавьте условную логику, например:

    <kml:Placemark>
        <xsl:choose>
            <!-- Our current context is an <Item> element.  Does this have a <cx> child element? -->
            <xsl:when test="cx">
                <kml:Circle>
                    <...snip.../>
                </kml:Circle>
            </xsl:when>
            <!-- Or does this have a <Lon> child element? -->
            <xsl:when test="Lon">
                <kml:Point>
                    <...snip.../>
                </kml:Point>
            </xsl:when>
            <!-- Sanity check: generally good practice to include an `otherwise` 
                to define what to do in case of unexpected input. -->
            <xsl:otherwise>
                <...snip.../>
            </xsl:otherwise>
        </xsl:choose>
    </kml:Placemark>

В вашем существующем коде элементы <kml:Circle> и <kml:Point> выводятся каждый раз - только содержимое каждого подчинено условной логике. Поэтому, если условие не выполнено, элемент все еще выводится - только без содержимого, генерируя пустые теги, которые вам не нужны.

В приведенных выше <xsl:choose> сами элементы <kml:Circle> и <kml:Point> генерируются только условно, поэтому вы не получите пустые элементы.

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