排序类别不在参考列表中的元素

时间:2018-09-10 20:46:38

标签: xml xslt

这是我上一个问题的跟进; Sorting on attribute collected from reference list

现在,我添加了两个VisitedCity元素,它们位于世界的一部分中,未在用于排序的参考列表中列出。我希望所有这些元素最终都在列表的末尾,并按第二个(日期)键在内部排序。

这是更新的源xml:

<?xml version="1.0" encoding="UTF-8"?> <Atlas>
    <Cities>
        <City id="1" worldPart="Africa">
            <Name>Luxor</Name>
            <Founded>-3200</Founded>
            <Location>Egypt</Location>
        </City>
        <City id="2" worldPart="Africa">
            <Name>Tripoli</Name>
            <Founded>-700</Founded>
            <Location>Libya</Location>
        </City>
        <City id="3" worldPart="Americas">
            <Name>Cholula</Name>
            <Founded>-200</Founded>
            <Location>Mexico</Location>
        </City>
        <City id="4" worldPart="Americas">
            <Name>Flores</Name>
            <Founded>-1000</Founded>
            <Location>Guatemala</Location>
        </City>
        <City id="5" worldPart="Europe">
            <Name>Argos</Name>
            <Founded>-5000</Founded>
            <Location>Greece</Location>
        </City>
        <City id="6" worldPart="Europe">
            <Name>Athens</Name>
            <Founded>-4000</Founded>
            <Location>Greece</Location>
        </City>
        <City id="7" worldPart="Asia">
            <Name>Varanasi</Name>
            <Founded>-1800</Founded>
            <Location>India</Location>
        </City>
        <City id="8" worldPart="Asia">
            <Name>Jakarta</Name>
            <Founded>397</Founded>
            <Location>Indonesia</Location>
        </City>
    </Cities>
    <VisitedCities lastUpdate="2018-09-10">
        <VisitedCity cityID="6">
            <Date>1883-08-26</Date>
            <Visitor>Dora</Visitor>
        </VisitedCity>
        <VisitedCity cityID="3">
            <Date>1907-01-02</Date>
            <Visitor>Nemo</Visitor>
        </VisitedCity>
        <VisitedCity cityID="4">
            <Date>1940-02-08</Date>
            <Visitor>Jimenez</Visitor>
        </VisitedCity>
        <VisitedCity cityID="7">
            <Date>2006-09-11</Date>
            <Visitor>Cook</Visitor>
        </VisitedCity>
        <VisitedCity cityID="2">
            <Date>1886-06-10</Date>
            <Visitor>James T. Kirk</Visitor>
        </VisitedCity>
        <VisitedCity cityID="8">
            <Date>1996-11-10</Date>
            <Visitor>Andree</Visitor>
        </VisitedCity>
    </VisitedCities> </Atlas>

所需的输出如下:

<?xml version="1.0" encoding="UTF-8"?>
<Atlas>
    <Cities>
        <City id="1" worldPart="Africa">
            <Name>Luxor</Name>
            <Founded>-3200</Founded>
            <Location>Egypt</Location>
        </City>
        <City id="2" worldPart="Africa">
            <Name>Tripoli</Name>
            <Founded>-700</Founded>
            <Location>Libya</Location>
        </City>
        <City id="3" worldPart="Americas">
            <Name>Cholula</Name>
            <Founded>-200</Founded>
            <Location>Mexico</Location>
        </City>
        <City id="4" worldPart="Americas">
            <Name>Flores</Name>
            <Founded>-1000</Founded>
            <Location>Guatemala</Location>
        </City>
        <City id="5" worldPart="Europe">
            <Name>Argos</Name>
            <Founded>-5000</Founded>
            <Location>Greece</Location>
        </City>
        <City id="6" worldPart="Europe">
            <Name>Athens</Name>
            <Founded>-4000</Founded>
            <Location>Greece</Location>
        </City>
        <City id="7" worldPart="Asia">
            <Name>Varanasi</Name>
            <Founded>-1800</Founded>
            <Location>India</Location>
        </City>
        <City id="8" worldPart="Asia">
            <Name>Jakarta</Name>
            <Founded>397</Founded>
            <Location>Indonesia</Location>
        </City>
    </Cities>
    <VisitedCities lastUpdate="2018-09-10">
        <VisitedCity cityID="2">
            <Date>1886-06-10</Date>
            <Visitor>James T. Kirk</Visitor>
        </VisitedCity>
        <VisitedCity cityID="6">
            <Date>1883-08-26</Date>
            <Visitor>Dora</Visitor>
        </VisitedCity>
        <VisitedCity cityID="3">
            <Date>1907-01-02</Date>
            <Visitor>Nemo</Visitor>
        </VisitedCity>
        <VisitedCity cityID="4">
            <Date>1940-02-08</Date>
            <Visitor>Jimenez</Visitor>
        </VisitedCity>
        <VisitedCity cityID="8">
            <Date>1996-11-10</Date>
            <Visitor>Andree</Visitor>
        </VisitedCity>
        <VisitedCity cityID="7">
            <Date>2006-09-11</Date>
            <Visitor>Cook</Visitor>
        </VisitedCity>
    </VisitedCities>
</Atlas>

据我了解,Martin Honnen在previous solution中使用的index-of()将包含空序列值,这些值会导致这些城市被丢弃或排在所有其他城市之前。有没有一种方法可以定义一个“后备”值来代替这些空值?还是我需要建立一个完整的参考列表来避免这种情况?

还是我完全误解了index-of()?请帮助我对这些不幸的城市进行分类!我使用XSLT 2.0。

1 个答案:

答案 0 :(得分:1)

如果没有找到该项目,index-of函数将返回空序列,因此您可以决定进行检查,并在这种情况下返回count($sort-order) + 1,XPath中的一种紧凑方法是

<xsl:sort select="(index-of($sort-order, key('city-by-id', @cityID)/@worldPart), count($sort-order) + 1)[1]"/>

https://xsltfiddle.liberty-development.net/eiZQaFJ/1

更长但也许更容易掌握的版本是使用`

if (empty(index-of($sort-order, key('city-by-id', @cityID)/@worldPart))) then count($sort-order) + 1 else index-of($sort-order, key('city-by-id', @cityID)/@worldPart)