如何在xml列表中检查两个代码?

时间:2016-11-10 20:31:42

标签: xml xpath xslt-1.0

我需要知道给定的产品清单是否包含两种特定产品。如果两者都存在,我需要忽略一个。如果只有其中一个存在,我需要保留该产品。

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如何为false且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>

1 个答案:

答案 0 :(得分:1)

我认为您的hasBoth变量存在问题。在创建时使用xsl:value-of,结果是一个字符串。

当您测试$hasBoth时,即使字符串值为&#34; false&#34;因为:

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']"/>