Я вижу две проблемы с этим XSLT (вопрос был помечен как 'xquery', я исправил это, обе технологии разные).
a) В XML каждый узел имеет уникальную идентичность.Поэтому сравнение двух узлов атрибута приводит к сравнению их значений, а не их значений.
//country[@id = @country]/name
означает, что процессор проверяет, имеет ли узел атрибута @id
такую же идентичность, что и узел атрибута @country
, что составляет false
.Это как две машины, по 4 пассажира в каждой, но одна машина - Toyota, а другая - Mercedes.Тойота не Мерседес, даже если оба перевозят 4 пассажиров.Даже если бы оба были Тойотами одной и той же модели / года выпуска / серии, это не совпало бы, так как даже два автомобиля одной и той же модели по-прежнему являются двумя разными автомобилями. и на возвращенный результат, который является всеми дочерними элементами соответствующих узлов элемента //city
, поэтому атрибут select
должен учитывать это.
Я обратилсяпервая проблема (а), упрощая способ обращения к name
из country
, просто принимая его как выражение XPath, которое перемещает иерархию узлов вверх на два уровня.Это будет работать, если все обрабатываемые вами узлы country
имеют одинаковую структуру.
Для второго вопроса (b) я применил относительное расположение ключей сортировки, то есть относительнофрагмент дерева результатов, полученный из шаблона (я полагаю, вы хотите отсортировать все страны в порядке убывания и все соответствующие города в пределах страны по возрастанию).
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<html>
<body>
<h1 align="center">Mondial</h1>
<table border="1">
<tr bgcolor="blue">
<th>Ciutat</th>
<th>Latitud</th>
<th>Longtitud</th>
<th>Pais</th>
</tr>
<xsl:for-each select="//city[@latitude >= '41.4']">
<xsl:sort select="../../name" order="descending"/>
<xsl:sort select="name"/>
<tr>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="@longitude"/></td>
<td><xsl:value-of select="@latitude"/></td>
<td><xsl:value-of select="parent::province/parent::country/name"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Другой альтернативный метод дляВаша таблица стилей XSLT будет тем, что называется методом «push» (в отличие от используемого здесь метода «pull»), где каждый объявляет шаблоны для всех точек интереса в файле XML, а затем позволяет процессору проходить через каждый изэти шаблоны соответствуют друг другу.Это удобно, особенно когда создаются сложные преобразования.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:strip-space elements="*"/>
<xsl:output method="html"/>
<xsl:template match="/">
<html>
<head><title></title></head>
<body>
<table border="1">
<tr bgcolor="blue">
<th>Ciutat</th>
<th>Latitud</th>
<th>Longtitud</th>
<th>Pais</th>
</tr>
<xsl:apply-templates select="mondial/country/province/city[@latitude >= '41.4']">
<xsl:sort select="parent::province/parent::country/name" order="descending"/>
<xsl:sort select="name"/>
</xsl:apply-templates>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="city[@latitude >= '41.4']">
<tr>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="@longitude"/></td>
<td><xsl:value-of select="@latitude"/></td>
<td><xsl:value-of select="../../name"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
Более того, последний шаблон мог быть написан
<xsl:template match="city[@latitude >= '41.4']">
<tr>
<td><xsl:apply-templates select="name"/></td>
<td><xsl:apply-templates select="@longitude"/></td>
<td><xsl:apply-templates select="@latitude"/></td>
<td><xsl:apply-templates select="../../name"/></td>
</tr>
</xsl:template>
, так как процессор XSL просто применяет его встроенные шаблоны , которые в этом случае просто принимают значение узла и вставляют его в результирующее дерево в заданной позиции.Смотри также «Тяни, Тяни, Дальше!»Боб Дюшарм , "Push vs. Pull" в XSL FAQ и очень приятное, краткое введение Эдди Уэлкера, "Преимущества XSLT в стиле push по сравнению с pull-style" для обзора этого метода.