Сравнивая логическое значение xs: в XSLT? - PullRequest
2 голосов
/ 20 ноября 2010

У меня есть XML-схема с элементом, определенным с типом xs: boolean, например:

<xs:element name="useful"
              minOccurs="1" maxOccurs="1"
              type="xs:boolean"/>

Я пытаюсь использовать блок выбора / когда / иного в XSL для вывода чего-то определенного на основе значения этого, например:

<xsl:choose>
   <xsl:when test="@useful = 0">No</xsl:when>
   <xsl:otherwise>Yes</xsl:otherwise>
</xsl:choose>

Я пробовал все варианты, которые я могу придумать для этого сравнения (используя true (), false (), 1, 0, удаляя @, используя // @), и всегда выводится «Да». Что я тут не так делаю?

РЕДАКТИРОВАТЬ (по запросу от Мартина Хоннена):

Вот пример используемого XML:

<?xml version="1.0"?>
<functions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:noNamespaceSchemaLocation="functions.xsd">
   <function>
      <name>func1</name>
      <useful>0</useful>
   </function>

   <function>
      <name>func2</name>
      <useful>1</useful>
   </function>
</functions>

Это вызывает проблемы с использованием xsl: template, я думаю, поэтому я использую xsl: for-each для циклического прохождения каждой функции и пытаюсь вывести что-то конкретное для каждого полезного тега. xsl: template можно использовать только на верхнем уровне xslt, верно?

Полный файл XSLT:

<?xml version='1.0' ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="/">
      <html><body>
         <h2>Functions</h2>
            <table border="1">
              <tr>
                  <th>Functions</th>
                  <th>Useful</th>
               </tr>
               <xsl:for-each select="functions/function">
                  <tr>
                     <td>
                        <xsl:value-of select="name"/>
                     </td>
                     <td>
                        <xsl:choose>
                           <xsl:when test="@useful = 0">No</xsl:when>
                           <xsl:otherwise>Yes</xsl:otherwise>
                        </xsl:choose>
                     </td>
                  </tr>
               </xsl:for-each>
            </table>
         </body></html>
      </xsl:template>
</xsl:stylesheet>

Ответы [ 2 ]

3 голосов
/ 20 ноября 2010

Я думаю, что схема определяет элемент, но вы проверяете значение атрибута - это может быть вашей главной проблемой.

<xsl:choose> 
   <xsl:when test="@useful = 0">No</xsl:when> 
   <xsl:otherwise>Yes</xsl:otherwise> 
</xsl:choose> 

Я перепробовал все варианты для этого сравнения (используя true(), false(), 1, 0, удаляя @, используя //@), и это всегда печатает «Да». Что я здесь делаешь неправильно?

Скорее всего, текущий узел не является элементом с атрибутом с именем useful.

Вот как работать в XSLT 1.0 с типом элемента useful, как определено схемой:

<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="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="useful/text()[. = 'true' or .='1']">
  Yes
 </xsl:template>

 <xsl:template match="useful/text()[. = 'false' or .='0']">
  No
 </xsl:template>
</xsl:stylesheet>

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

<t>
    <useful>true</useful>
    <useful>false</useful>
    <useful>1</useful>
    <useful>0</useful>
</t>

желаемый, правильный результат выдается :

<t>
    <useful>
  Yes
 </useful>
    <useful>
  No
 </useful>
    <useful>
  Yes
 </useful>
    <useful>
  No
 </useful>
</t>

В XSLT 2.0 (процессор с поддержкой схемы) вам необходимо импортировать схему (используйте <xsl:import-schema>), тогда вы можете просто использовать:

('no', 'yes')[number(useful)+1]

где текущий узел является родителем элемента useful.

1 голос
/ 20 ноября 2010

Ваша схема определяет элемент с именем «полезный», но схема вообще не имеет значения, если вы не пытаетесь использовать XSLT 2.0 с поддержкой схемы.

Выполнение @useful в XPath выбирает атрибут с таким именемузел контекста, который не имеет никакого смысла в имеющейся у вас схеме, поскольку он определяет элемент.Итак, покажите нам ваш экземпляр XML, который обрабатывает XSLT, и мы покажем вам некоторый код XSLT:

<xsl:template match="useful">
  <xsl:choose>
    <xsl:when test=". = 'false' or . = 0">No</xsl:when>
    <xsl:otherwise>Yes</xsl:otherwise>
  </xsl:choose>
</xsl:template>

С помощью XSLT 2.0 с поддержкой схемы вы можете выполнить

<xsl:template match="useful">
  <xsl:value-of select="if (data(.)) then 'Yes' else 'No'"/>
</xsl:template>
...