2016-11-10 3 views
2

Мне нужно знать, содержит ли данный список продуктов два конкретных продукта. Если оба существуют, мне нужно их игнорировать. Если существует только один из них, мне нужно сохранить этот продукт.Как проверить наличие двух кодов в списке xml?

XML 1

<ns0:Items xmlns:ns0="abc"> 
    <ns0:Item> 
    <ns0:Code>X1</ns0:Code> <!-- keep this because it is the only one --> 
    <ns0:Quantity>1</ns0:Quantity> 
    </ns0:Item> 
</ns0:Items> 

XML 2

<ns0:Items xmlns:ns0="abc"> 
    <ns0:Item> 
    <ns0:Code>X1</ns0:Code> <!-- ignore this because we have another valid product --> 
    <ns0:Quantity>1</ns0:Quantity> 
    </ns0:Item> 
    <ns0:Item> 
    <ns0:Code>M1</ns0:Code> 
    <ns0:Quantity>1</ns0:Quantity> 
    </ns0:Item> 
</ns0:Items> 

XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="abc" version="1.0"> 
    <xsl:output method="xml" indent="yes" encoding="utf-16" omit-xml-declaration="no" /> 
    <xsl:template match="ns0:Items"> 
    <Items> 
     <xsl:variable name="hasBoth"> 
     <xsl:value-of select="boolean(ns0:Item/ns0:Code[.='M1']) and boolean(ns0:Item/ns0:Code[.='X1'])" /> 
     </xsl:variable> 
     <xsl:for-each select="ns0:Item"> 
     <xsl:variable name="validItem"> 
      <xsl:choose> 
      <xsl:when test="$hasBoth and ns0:Code='X1' and ns0:Quantity=1"> 
       <xsl:value-of select="0"/> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:value-of select="1"/> 
      </xsl:otherwise> 
      </xsl:choose> 
     </xsl:variable> 
     <both> 
      <xsl:value-of select="$hasBoth"/> 
     </both> 
     <expr> 
      <xsl:value-of select="$hasBoth and ns0:Code='X1' and ns0:Quantity=1"/> 
     </expr> 
     <valid> 
      <xsl:value-of select="$validItem"/> 
     </valid> 
     <xsl:if test="$validItem = 1"> 
      <SalesOrderDetail> 
      <xsl:copy-of select="."/> 
      </SalesOrderDetail> 
     </xsl:if> 
     </xsl:for-each> 
    </Items> 
    </xsl:template> 
</xsl:stylesheet> 

Результат 1 - это неправильно, он удаляет X1 продукт, даже если он является единственным, как может $ hasBoth быть ложным и expr быть истинным?

<Items> 
    <both>false</both> 
    <expr>true</expr> 
    <valid>0</valid> 
</Items> 

Результат 2 - правильно, он удаляет X1, продукт

<Items> 
    <both>true</both> 
    <expr>true</expr> 
    <valid>0</valid> 
    <both>true</both> 
    <expr>false</expr> 
    <valid>1</valid> 
    <SalesOrderDetail> 
    </SalesOrderDetail> 
</Items> 
+0

Вы два входа и два результата, один из них неправильно, как правильный результат 1 должен быть? –

ответ

1

Я думаю, что это проблема с hasBoth переменной. Когда вы используете xsl:value-of при его создании, результатом является строка.

При тестировании $hasBoth это правда, даже если строковое значение «ложь», потому что:

boolean("false") = true() 

Кроме того, вы не должны использовать boolean().

Попробуйте это изменить:

<xsl:variable name="hasBoth"> 
    <xsl:value-of select="boolean(ns0:Item/ns0:Code[.='M1']) and boolean(ns0:Item/ns0:Code[.='X1'])" /> 
</xsl:variable> 

к этому:

<xsl:variable name="hasBoth" 
     select="ns0:Item/ns0:Code[.='M1'] and ns0:Item/ns0:Code[.='X1']"/> 
+1

вы подумали бы, что, имея опыт работы с javascript, я бы научил меня быть уверенным, что правильно сравнивал типы! Благодарю. – Nate