XPath, получение значения минимального атрибута

#xslt #xpath #xslt-1.0 #xpath-2.0

#xslt #xpath #xslt-1.0 #xpath-2.0

Вопрос:

ИТАК, я никогда раньше не использовал XSLT, и я использовал XPath только в его простейшей форме. У меня есть элемент Xml «Earth» с двумя атрибутами Stamina и willpower. Оба содержат числа. То, что я пытаюсь сделать, это отобразить рядом со словом «Земля» значение наименьшего из этих атрибутов. Кажется, я не могу понять, как вызывать функции в XPath.

Вот мой XSLT

     <?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:fn="http://www.w3.org/2005/xpath-functions"
  version="2.0">
  <!--<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> 
    -->

  <xsl:output method="html" indent="yes"/>

  <xsl:template match="/">
    <html>
      <body>
        <xsl:apply-templates select="//Rings"/>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="//Rings">
    <h2>Rings</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>Earth</th>
        <th>
          <xsl:value-of select="fn:min(fn:number(Earth/@*))"/>
        </th>
      </tr>
      </tr>
    </table>
  </xsl:template>
</xsl:stylesheet>
  

Комментарии:

1. Все примеры для XLST, которые я нахожу в W3eC, слишком тривиальны.

Ответ №1:

MS Visual Studio поставляется в комплекте с XSLT-процессором .NET XslCompiledTransform, и это процессор XSLT 1.0.

С другой стороны, min() это стандартная функция в XPath 2.0, а не в XPath 1.0. XSLT 1.0 использует только XPath 1.0.

Решение проблемы на XSLT 1.0:

 <xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="Earth">
     <xsl:value-of select=
      "@*[not(. > ../@*)][1]"/>
 </xsl:template>
</xsl:stylesheet>
  

когда это преобразование применяется к следующему XML-документу (поскольку вы его не предоставили!):

 <Rings>
 <Earth stamina="3" willpower="6"/>
</Rings>
  

получен желаемый, правильный результат:

 3
  

В .NET можно использовать сторонний процессор XSLT 2.0, такой как Saxon.NET или XQSharp. Ниже представлено решение XSLT 2.0:

 <xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="Earth">
     <xsl:sequence select="min(@*)[1]"/>
 </xsl:template>
</xsl:stylesheet>
  

Комментарии:

1. Отлично, спасибо. Я думаю, что в этом примере я должен быть в состоянии разобраться со всем, что мне нужно знать о XSLT.

2. @Oxinabox: Добро пожаловать. Я надеюсь, вам нужно знать о XSLT еще больше 🙂

Ответ №2:

Также обратите внимание, что min(number(@*)) это неверно в XPath 2.0 — вы не можете применить функцию number() к последовательности узлов, чтобы получить последовательность чисел. Так и должно быть min(@*/number()) . Однако, если входные данные не проверены, все атрибуты будут нетипизированными, а функция min() автоматически преобразует нетипизированные значения в числа. Однако, если есть атрибуты, которые не являются числовыми, то автоматическое преобразование вызовет ошибку, в то время как использование number() сгенерирует значение NaN, что приведет к тому, что результат min() также будет NaN . Если вам нужно минимальное значение всех этих числовых атрибутов, попробуйте min(@*[. castable as xs:double]) .

Ответ №3:

min() Функция доступна только в XSLT 2.0. Вам следует попробовать использовать процессор 2.0 (Saxon).

Комментарии:

1. Я использую MS Visual studio 2010. (и я предполагаю, что это поддерживает?) Я знал, что min() — это XSLT 2.0 (обратите внимание, что вопрос был помечен как Xpath 2.0), я думал, что неправильно использую функции / пространства имен

2. Процессоры Microsoft XSLT, такие как MSXML 3 и MSXML 6 в мире COM, а также XslCompiledTransform в . ЧИСТЫЙ мир — это процессоры XSLT 1.0. Однако существуют сторонние реализации XSLT 2.0, а именно AltovaXML в мире COM и Saxon 9 и XQSharp в . ЧИСТЫЙ мир. Таким образом, если вы хотите использовать функции XPath 2.0 в XSLT, вам необходимо использовать процессор XSLT 2.0. Обратите внимание, что затем вы можете использовать эти функции без использования префикса.

3. По-видимому, это только XLST 1 с visual studio… (РЕДАКТИРОВАТЬ: О, я пропустил сообщение Мартинса)