Ответ Диво - хороший.
Однако он ограничивает любую возможную фильтрацию указанием имени и значения дочернего элемента.
Хорошо знать, что в качестве параметра можно передать функцию (что составляет a). Эта очень мощная концепция реализована в FXSL - библиотеке функционального программирования для XSLT. FXSL полностью написан в XSLT.
Вот подходящий пример, используя the filter function/template. Мы передаем фильтр в качестве параметра шаблону, который выполняет фильтрацию. Фильтр может быть любым кодом/логикой. В этом конкретном случае мы передаем в качестве параметра ссылку на шаблон, который проверяет, является ли число четным. Полное преобразование выводит только те элементы «num», значение которых равно четному числу.
Мы могли бы легко пройти любой другой фильтр, используя точно такую же технику: для фильтрации (ип) четные числа, квадраты, простые числа, ... и т.д.
ли к сведению, что один Безразлично 't должен написать себе шаблон фильтра' - он написан раз и навсегда и предоставляется библиотекой FXSL. В результате вы обычно используете директиву < xsl: import /> для импорта шаблона «фильтр» и многие другие полезные функции/шаблоны, уже предоставленные FXSL.
Преобразование ниже:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
xmlns:myIsEven="myIsEven"
>
<xsl:import href="filter.xsl"/>
<!-- To be applied on numList.xml -->
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<myIsEven:myIsEven/>
<xsl:template match="/">
<xsl:variable name="vIsEven"
select="document('')/*/myIsEven:*[1]"/>
Filtering by IsEven:
<xsl:call-template name="_filter">
<xsl:with-param name="pList" select="/*/*"/>
<xsl:with-param name="pController" select="$vIsEven"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="myIsEven" mode="f:FXSL"
match="myIsEven:*">
<xsl:param name="arg1"/>
<xsl:if test="$arg1 mod 2 = 0">1</xsl:if>
</xsl:template>
</xsl:stylesheet>
при нанесении на этом источнике XML документа:
<nums>
<num>01</num>
<num>02</num>
<num>03</num>
<num>04</num>
<num>05</num>
<num>06</num>
<num>07</num>
<num>08</num>
<num>09</num>
<num>10</num>
</nums>
производит желаемое (фильтрованный) результат, содержащий только узлы с четными значениями:
Filtering by IsEven:
<num>02</num>
<num>04</num>
<num>06</num>
<num>08</num>
<num>10</num>
Дополнительную информацию о функциональном программировании в XSLT можно найти на page of FXSL, а сама библиотека может быть загружена с ее sourceforce project.
Чтобы вернуться к конкретной проблеме:
Эта трансформация:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
xmlns:myFilter="myFilter"
>
<xsl:import href="filter.xsl"/>
<!-- To be applied on Orders.xml -->
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<myFilter:myFilter/>
<xsl:template match="/">
<xsl:variable name="vFilter"
select="document('')/*/myFilter:*[1]"/>
Filtering by PRICE < 15:
<xsl:call-template name="_filter">
<xsl:with-param name="pList" select="/*/*"/>
<xsl:with-param name="pController" select="$vFilter"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="myFilter" mode="f:FXSL"
match="myFilter:*">
<xsl:param name="arg1"/>
<xsl:if test="$arg1/PRICE < 15">1</xsl:if>
</xsl:template>
</xsl:stylesheet>
при нанесении на этот источник XML документа:
<ORDERS>
<ORDER>
<PRICE>10</PRICE>
</ORDER>
<ORDER>
<PRICE>7</PRICE>
</ORDER>
<ORDER>
<PRICE>22</PRICE>
</ORDER>
<ORDER>
<PRICE>16</PRICE>
</ORDER>
<ORDER>
<PRICE>13</PRICE>
</ORDER>
<ORDER>
<PRICE>19</PRICE>
</ORDER>
</ORDERS>
производит желаемого результата:
Filtering by PRICE < 15:
<ORDER>
<PRICE>10</PRICE>
</ORDER>
<ORDER>
<PRICE>7</PRICE>
</ORDER>
<ORDER>
<PRICE>13</PRICE>
</ORDER>
Cheers for thi s, прекрасно работает. – 2008-11-28 11:59:29
Росс, для более общего решения см. Мой ответ. Cheers – 2008-11-29 03:44:32