XSLT для возврата логического значения, если все теги равны значению

#xml #xslt

#xml #xslt

Вопрос:

У меня есть xml:

 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
    <success>0</success>
    <success>0</success>
    <success>1</success>
</soapenv:Body>
  

И я хочу реализовать логику, которая вернет true, если один из тегов успеха равен 0, и false, если все они равны 0.

Пока у меня есть, но я не знаю, как заставить xslt повторно настроить errorFlag= false, если все они равны = 0:

 <xsl:template match="/">
  <xsl:call-template name="test" />
</xsl:template>

 <xsl:template match="/soapenv:Envelope/soapenv:Body" name ="test">
   <errorFlag>
     <xsl:if test="contains(.,'0')">true</xsl:if>
   </errorFlag>
</xsl:template>
  

Требуемый вывод — только одно поле:

 <errorFlag>true<errorFlag> (if all are success=0)
  

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

1. что вы хотите вывести

2. отредактировал сообщение

3. Какой результат вы хотели бы получить, если бы был только один <success>0</success> ? «true», потому что есть один элемент, равный 0, или «false», потому что «все» (единственный) имеют значение 0?

4. Примечание : когда вы вызываете шаблон по имени, его match атрибут игнорируется. Ваш . выбирает весь документ, потому что вы все еще находитесь в контексте `/`.

Ответ №1:

Как насчет:

 <xsl:template match="/">
    <errorFlag>
         <xsl:value-of select="not(/soapenv:Envelope/soapenv:Body/success=1)" />
    </errorFlag>
</xsl:template>
  

Или (требуется XSLT 2.0):

 <xsl:template match="/">
    <errorFlag>
        <xsl:value-of select="every $item in /soapenv:Envelope/soapenv:Body/success satisfies $item=0"/>
    </errorFlag>
</xsl:template>
  

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

1. Ответ хороший, но я использую WSO2 для создания своего сервиса, который использует этот XSLT, но каким-то образом, когда он преобразует сообщение с его помощью, он возвращает true, когда все они равны 1.

2. Боюсь, я не могу воспроизвести вашу проблему: xsltfiddle. liberty-development.net/pPzifph

Ответ №2:

Я хочу реализовать логику, которая вернет true, если один из тегов успеха равен 0, и false, если все они равны 0.

Сначала давайте создадим таблицу истинности:

 All zeros | None zero | Some zero, others not
-------------------------------------------
  False   |   False   |        True
  

Во-вторых, сравнение набора узлов в XPath является существующим. Итак:

 boolean(/soapenv:Envelope/soapenv:Body[success = 0 and success != 0])
  

Он вернет true или false логическое значение.

Этот ввод

 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
    <success>0</success>
    <success>0</success>
    <success>1</success>
</soapenv:Body>
</soapenv:Envelope>
  

С помощью этой таблицы стилей

 <xsl:stylesheet 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" version="1.0">
   <xsl:template match="/">
      <xsl:value-of 
         select="boolean(
                    /soapenv:Envelope
                       /soapenv:Body[
                          success = 0 and success != 0
                       ]
                 )"/>
   </xsl:template>
</xsl:stylesheet>
  

ВОЗВРАТ

 true
  

Проверьте это в http://www.utilities-online.info/xsltransformation/?save=ceed7a50-6a47-4c2c-b344-86ad3b3b0d92-xsltransformation

Ответ №3:

 <?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />

<xsl:key name="succKey" match="success" use="." />

<xsl:template match="/">
    <xsl:call-template name="test" />
</xsl:template>

<xsl:template match="/soapenv:Envelope/soapenv:Body" name="test">
    <xsl:variable name="key-count"
        select="count(//success[generate-id() =
                               generate-id(key('succKey', .))])" />
    <errorFlag>
        <xsl:choose>
            <xsl:when test="$key-count = 1">
                <xsl:text>true</xsl:text>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text>false</xsl:text>
            </xsl:otherwise>
        </xsl:choose>
    </errorFlag>
</xsl:template>
</xsl:stylesheet>
  

http://xsltfiddle.liberty-development.net/6r5Gh33

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

1. Вы можете изменить значение true / false в xsl:text в зависимости от вашего условия, поскольку ваши два предложения противоречат вопросу о том, когда оно должно быть true, а когда оно должно быть false. Спасибо.

2. Если я правильно понимаю вопрос, этот ответ неверен. Оно вернется, true когда все success элементы будут равны 0 или когда все success элементы будут равны 1: xsltfiddle. liberty-development.net/6r5Gh33/1 (не говоря уже о том, насколько это ненужно запутанно).

3. @michael.hor257k: Это уже объяснялось в моем предыдущем комментарии.