Как использовать операторы внутри select в теге xsl?

У меня XML-файл (некоторая служебная документация) выглядит так:

<?xml version="1.0" encoding="UTF-8"?>
<apis>
    <api min="2.2" max="3.0">
        <resource name="products">
            <description>products from 2.2 to 3.0</description>
        </resource>
        <resource name="brands">
            <description>brands from 2.2 to 3.0</description>
        </resource>
    </api>
    <api min="1.0" max="2.2">
        <resource name="products">
            <description>products from 1.0 to 2.2</description>
        </resource>
    </api>
    <api min="2.1" max="2.2">
        <resource name="brands">
            <description>brands from 2.1 to 2.2</description>
        </resource>
    </api>
    <api min="1.0" max="2.1">
        <resource name="brands">
            <description>brands from 1.0 to 2.1</description>
        </resource>
    </api>
</apis>

И когда я хочу взять оба описания ресурсов в версии API, например 2.1, используя groovy и XmlParser, я могу сделать это:

def rawXml = new XmlParser().parse ( 'file.xml' )
rawXml.api.findAll {
         node -> node.@min <= '2.1' && node.@max > '2.1' 
}.resource.description

Теперь я хочу сделать это, но в файл HTML с помощью XSLT. Я пытаюсь:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="apis">
        <html>
            <body>
                <table>
                    <tr>
                        <th>Resource name</th>
                        <th>Resource description</th>
                    </tr>
                    <xsl:for-each select="api[@min<='2.1'] and api[@max>'2.1']">
                        <xsl:for-each select="resource">
                            <tr>
                                <td>
                                    <xsl:value-of select="@name"/>
                                </td>
                                <td>
                                    <xsl:value-of select="description"/>
                                </td>
                            </tr>
                        </xsl:for-each>
                    </xsl:for-each>
                </table>
            </body>
        </html>
    </xsl:template>

</xsl:stylesheet>

Но это не работает. Я заметил, что проблема связана с операторами '‹=', '>' и 'и'. я изменил

'api[@min<='2.1'] and api[@max>'2.1']'

to

'api[@min&lt;='2.1']'

or to

api[@max&gt;'2.1']

и это работает. Но

'api[@min&lt;='2.1'] and api[@max&gt;'2.1']'

нет. http://www.w3schools.com/xsl/xpath_operators.asp сообщает, что следует для xpath, но с выбором xsl есть проблемы?


person Elej    schedule 14.12.2015    source источник


Ответы (1)


Поместите оба логических выражения в один предикат ([]), если вы хотите применить оба одновременно к одному элементу api:

<xsl:for-each select="api[@min &lt;= '2.1' and @max &gt; '2.1']">

Приведенное выше должно корректно перебирать элементы api, у которых значение атрибута min меньше или равно 2.1, а значение атрибута max больше 2.1.

person har07    schedule 14.12.2015
comment
Возможно, вам также захочется убрать кавычки вокруг 2.1, так как, по-видимому, здесь требуется числовое, а не лексическое сравнение. - person kjhughes; 14.12.2015
comment
В XPath 1.0 операторы < и > всегда выполняют числовое сравнение (оба операнда преобразуются в числовые), но в каком-то смысле еще более важно сделать это однозначно числовым сравнением, потому что в противном случае у вас возникнет проблема совместимости при переходе на 2.0. - person Michael Kay; 14.12.2015