有人会让我知道下面的XSL有什么问题吗?

时间:2015-06-26 20:37:05

标签: xml xslt

我使用Contivo创建了这个xslt映射,但它不适用于下面的XML。 有人能够辨别出什么是错的吗?

我花了一些时间研究它,但却无法弄清楚出了什么问题。

这是XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<!-- IMPORTANT: If this transform will be run using Xalan, then version 2.5.1 or higher is required. -->
<!-- Copyright (c) 2008 Contivo, Inc. All Rights Reserved.-->
<!-- NOTE: DataPower supports the Xalan:nodeset() function. -->
<!-- This transform was created by Analyst version 3.11.2.2. -->
<xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:xalan="http://xml.apache.org/xalan"
     xmlns:func="http://exslt.org/functions"
     xmlns:ctvf="http://www.contivo.com/xslt/extensions"
     xmlns:date="http://exslt.org/dates-and-times"
     xmlns:dp="http://www.datapower.com/extensions"
     xmlns:tns="http://schemas.datacontract.org/2004/07/Inventory.Data.Models"
     xmlns:xs2="http://integration.com/interfaces/queryDirectInventory/v1/queryDirectInventory.xsd"
     extension-element-prefixes="func ctvf date dp"
     exclude-result-prefixes="xalan tns s">

    <xsl:variable name='_root' select='/'/>
    <xsl:template match='/'>
        <xsl:variable name="__MappingResults">
        <xsl:value-of select="ctvf:trim($_root//tns:InventoryInquiryApiResponse[1]/tns:InventoryInquiryApiResult[1]/tns:SkuAvailabilities[1]/tns:SkuAvailabilityResponse[1]/tns:AvailabilityIndicator[1])"/>
            <e>
                <xsl:attribute name="n">xs2:queryDirectInventoryResponse</xsl:attribute>
                <xsl:attribute name="m">t</xsl:attribute>
                <xsl:attribute name="d">f</xsl:attribute>
                <e>
                    <xsl:attribute name="n">xs2:availabilityList</xsl:attribute>
                    <xsl:attribute name="m">t</xsl:attribute>
                    <xsl:attribute name="d">f</xsl:attribute>
                    <e>
                        <xsl:attribute name="n">xs2:availabilityList</xsl:attribute>
                        <xsl:attribute name="m">t</xsl:attribute>
                        <xsl:attribute name="d">f</xsl:attribute>
                        <xsl:attribute name="m">l</xsl:attribute>
                        <xsl:for-each select="$_root//tns:InventoryInquiryApiResponse[1]/tns:InventoryInquiryApiResult[1]/tns:SkuAvailabilities[1]/tns:SkuAvailabilityResponse">
                            <e>
                                <xsl:attribute name="n">xs2:availabilityList</xsl:attribute>
                                <xsl:attribute name="m">f</xsl:attribute>
                                <xsl:attribute name="d">f</xsl:attribute>
                                <e>
                                    <xsl:attribute name="n">xs2:availabilityInd</xsl:attribute>
                                    <xsl:attribute name="m">f</xsl:attribute>
                                    <xsl:attribute name="d">f</xsl:attribute>
                                    <xsl:value-of select="ctvf:trim(string(./tns:AvailabilityIndicator[1]))"/>
                                </e>
                                <e>
                                    <xsl:attribute name="n">xs2:availableQuantity</xsl:attribute>
                                    <xsl:attribute name="m">f</xsl:attribute>
                                    <xsl:attribute name="d">f</xsl:attribute>
                                    <xsl:value-of select="ctvf:testForNullNumber(./tns:AvailableQuantity[1], &quot;&quot;)"/>
                                </e>
                                <e>
                                    <xsl:attribute name="n">xs2:zipCode</xsl:attribute>
                                    <xsl:attribute name="m">f</xsl:attribute>
                                    <xsl:attribute name="d">f</xsl:attribute>
                                    <xsl:value-of select="ctvf:trim(./tns:PostalCode[1])"/>
                                </e>
                                <e>
                                    <xsl:attribute name="n">xs2:itemId</xsl:attribute>
                                    <xsl:attribute name="m">f</xsl:attribute>
                                    <xsl:attribute name="d">f</xsl:attribute>
                                    <xsl:value-of select="ctvf:trim(./tns:Sku[1])"/>
                                </e>
                                <e>
                                    <xsl:attribute name="n">xs2:statusMessageInfo</xsl:attribute>
                                    <xsl:attribute name="m">f</xsl:attribute>
                                    <xsl:attribute name="d">f</xsl:attribute>
                                    <e>
                                        <xsl:attribute name="n">xs2:statusMessageCode</xsl:attribute>
                                        <xsl:attribute name="m">t</xsl:attribute>
                                        <xsl:attribute name="d">f</xsl:attribute>
                                        <xsl:value-of select="ctvf:trim(./tns:StatusMessage[1])"/>
                                    </e>
                                    <e>
                                        <xsl:attribute name="n">xs2:statusMessageText</xsl:attribute>
                                        <xsl:attribute name="m">f</xsl:attribute>
                                        <xsl:attribute name="d">f</xsl:attribute>
                                        <xsl:value-of select="ctvf:convertNumber(ctvf:trim(string(./tns:StatusMessageCode[1])))"/>
                                    </e>
                                </e>
                            </e>
                        </xsl:for-each>
                        <e>
                            <xsl:attribute name="n">xs2:availabilityList</xsl:attribute>
                            <xsl:attribute name="m">t</xsl:attribute>
                            <xsl:attribute name="d">f</xsl:attribute>
                            <xsl:attribute name="m">e</xsl:attribute>
                            <e>
                                <xsl:attribute name="n">xs2:statusMessageInfo</xsl:attribute>
                                <xsl:attribute name="m">f</xsl:attribute>
                                <xsl:attribute name="d">f</xsl:attribute>
                                <xsl:attribute name="m">e</xsl:attribute>
                                <e>
                                    <xsl:attribute name="n">xs2:statusMessageCode</xsl:attribute>
                                    <xsl:attribute name="m">t</xsl:attribute>
                                    <xsl:attribute name="d">f</xsl:attribute>
                                </e>
                            </e>
                        </e>
                    </e>
                </e>
            </e>
        </xsl:variable>

        <xsl:apply-templates select='xalan:nodeset($__MappingResults)' mode="eliminateEmptyTags"/>
    </xsl:template>

    <xsl:template match="a" mode="eliminateEmptyTags">
        <xsl:if test='@v != "" or @m = "t"'>
            <xsl:attribute name="{@n}">
                <xsl:value-of select='@v' />
            </xsl:attribute>
        </xsl:if>
    </xsl:template>

    <xsl:template match="e" mode="eliminateEmptyTags">
        <xsl:choose>
            <xsl:when test='@m = "f"'>
                <xsl:if test='descendant-or-self::*[text() != ""][@d = "f"][1]/text() != "" or descendant-or-self::a[@v != ""][@d = "f"][1]/@v != ""'>
                    <xsl:choose>
                        <xsl:when test='@n !=""'>
                            <xsl:element name="{@n}">
                                <xsl:apply-templates select='a' mode="eliminateEmptyTags"/>
                                <xsl:value-of select='text()' />
                                <xsl:for-each select='./namespace::*'>
                                    <xsl:copy/>
                                </xsl:for-each>
                                <xsl:apply-templates select='e' mode="eliminateEmptyTags"/>
                            </xsl:element>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:apply-templates select='e' mode="eliminateEmptyTags"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:if>
            </xsl:when>
            <xsl:when test='@m = "l"'>
                <xsl:choose>
                    <xsl:when test='child::e[@m != "e"]/descendant-or-self::*[text() != ""][@d = "f"][1]/text() != "" or child::e[@m != "e"]/descendant-or-self::a[@v != ""][@d = "f"][1]/@v != ""'>
                        <xsl:apply-templates select='e[@m != "e"]' mode="eliminateEmptyTags"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:apply-templates select='e[@m = "e"]' mode="eliminateEmptyTags"/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:otherwise>
                <xsl:choose>
                    <xsl:when test='@n !=""'>
                        <xsl:element name="{@n}">
                            <xsl:apply-templates select='a' mode="eliminateEmptyTags"/>
                            <xsl:value-of select='text()' />
                            <xsl:for-each select='./namespace::*'>
                                <xsl:copy/>
                            </xsl:for-each>
                            <xsl:apply-templates select='e' mode="eliminateEmptyTags"/>
                        </xsl:element>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:apply-templates select='e' mode="eliminateEmptyTags"/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>


    <!--=========================================================================-->

    <xsl:template name="trimAll">
        <xsl:param name="trimMe"/>
        <xsl:choose>
            <xsl:when test="contains($trimMe, ' ')">
                <xsl:call-template name="trimAll">
                    <xsl:with-param name="trimMe">
                        <xsl:value-of select='concat(substring-before($trimMe, " "), substring-after($trimMe, " "))'/>
                    </xsl:with-param>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select='$trimMe'/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template name="trimLeft">
        <xsl:param name="trimMe"/>
        <xsl:choose>
            <xsl:when test="starts-with($trimMe, ' ')">
                <xsl:call-template name="trimLeft">
                    <xsl:with-param name="trimMe" select='substring-after($trimMe, " ")'/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select='$trimMe'/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template name="trimRight">
        <xsl:param name="trimMe"/>
        <xsl:choose>
            <xsl:when test="substring($trimMe, string-length($trimMe), 1) = ' '">
                <xsl:call-template name="trimRight">
                    <xsl:with-param name="trimMe" select='substring($trimMe, 1, string-length($trimMe) - 1)'/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select='$trimMe'/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template name="trimBoth">
        <xsl:param name="trimMe"/>
        <xsl:variable name="result">
            <xsl:call-template name="trimRight">
                <xsl:with-param name="trimMe" select='$trimMe'/>
            </xsl:call-template>
        </xsl:variable>
        <xsl:variable name="resultb">
            <xsl:call-template name="trimLeft">
                <xsl:with-param name="trimMe" select='$result'/>
            </xsl:call-template>
        </xsl:variable>
        <xsl:value-of select='$resultb'/>
    </xsl:template>

    <!--=========================================================================-->

    <func:function name="ctvf:testForNullNumber">
        <xsl:param name="node"/>
        <xsl:param name="defaultValue"/>
        <xsl:choose>
            <xsl:when test="local-name($node) = ''">
                <func:result select="$defaultValue"/>
            </xsl:when>
            <xsl:when test="string-length(normalize-space(string($node))) = 0">
                <func:result select="$defaultValue"/>
            </xsl:when>
            <xsl:otherwise>
                <func:result select="number($node)"/>
            </xsl:otherwise>
        </xsl:choose>
    </func:function>

    <!--=========================================================================-->
    <func:function name="ctvf:convertNumber">
        <xsl:param name="val"/>
        <xsl:variable name="strVal" select="string($val)"/>
        <xsl:choose>
            <xsl:when test="$strVal = 'NaN'">
                <func:result select="''"/>
            </xsl:when>
            <xsl:otherwise>
                <func:result select="$strVal"/>
            </xsl:otherwise>
        </xsl:choose>
    </func:function>

    <!--=========================================================================-->

    <func:function name="ctvf:trim">
        <xsl:param name="param" select="''"/>
        <xsl:variable name="in" select="string($param)"/>
        <xsl:variable name="len" select="string-length($in)"/>
        <xsl:choose>
            <xsl:when test="$len &gt; 0 and (ctvf:isWhitespace(substring($in, 1, 1)) or ctvf:isWhitespace(substring($in, $len)))">
                <xsl:variable name="first" select="ctvf:doTrimGetFirst($in, 1, $len)"/>
                <func:result select="substring($in, $first, ctvf:doTrimGetLast($in, $len, $len) - $first + 1)"/>
            </xsl:when>
            <xsl:otherwise>
                <func:result select="$in"/>
            </xsl:otherwise>
        </xsl:choose>
    </func:function>

    <func:function name="ctvf:isWhitespace">
        <xsl:param name="char"/>
        <func:result select="$char = '&#x20;' or $char = '&#x9;' or $char = '&#xD;' or $char = '&#xA;'"/>
    </func:function>

    <func:function name="ctvf:doTrimGetFirst">
        <xsl:param name="in"/>
        <xsl:param name="index"/>
        <xsl:param name="len"/>
        <xsl:choose>
            <xsl:when test="($index &lt;= $len) and ($index &lt;= 350) and ctvf:isWhitespace(substring($in, $index, 1))">
                <func:result select="ctvf:doTrimGetFirst($in, $index + 1, $len)"/>
            </xsl:when>
            <xsl:otherwise>
                <func:result select="$index"/>
            </xsl:otherwise>
        </xsl:choose>
    </func:function>

    <func:function name="ctvf:doTrimGetLast">
        <xsl:param name="in"/>
        <xsl:param name="index"/>
        <xsl:param name="len"/>
        <xsl:choose>
            <xsl:when test="($index &gt;= 1) and ($len - $index &lt;= 350) and ctvf:isWhitespace(substring($in, $index, 1))">
                <func:result select="ctvf:doTrimGetLast($in, $index - 1, $len)"/>
            </xsl:when>
            <xsl:otherwise>
                <func:result select="$index"/>
            </xsl:otherwise>
        </xsl:choose>
    </func:function>

</xsl:stylesheet>

这是XML:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header />
  <s:Body>
    <InventoryInquiryApiResponse xmlns="http://tempuri.org/">
      <InventoryInquiryApiResult xmlns:a="http://schemas.datacontract.org/2004/07/Inventory.Data.Models" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <a:SkuAvailabilities>
          <a:SkuAvailabilityResponse>
            <a:AvailabilityIndicator>true</a:AvailabilityIndicator>
            <a:AvailableQuantity>1</a:AvailableQuantity>
            <a:PostalCode>12065</a:PostalCode>
            <a:Sku>sku</a:Sku>
            <a:StatusMessage>OK</a:StatusMessage>
            <a:StatusMessageCode>200</a:StatusMessageCode>
          </a:SkuAvailabilityResponse>
        </a:SkuAvailabilities>
      </InventoryInquiryApiResult>
    </InventoryInquiryApiResponse>
  </s:Body>
</s:Envelope>

2 个答案:

答案 0 :(得分:3)

您的XSL可能存在(并且可能存在)各种错误。跳到眼睛的第一件事( s列表中删除未声明的exclude-result-prefixes前缀后)是您没有使用源XML的正确名称空间。

例如,在您的第一个选择中:

<xsl:value-of select="ctvf:trim($_root//tns:InventoryInquiryApiResponse[1]/tns:InventoryInquiryApiResult[1]/tns:SkuAvailabilities[1]/tns:SkuAvailabilityResponse[1]/tns:AvailabilityIndicator[1])"/>

您为所有位置步骤使用相同的tns:前缀 - 但在您的XML中,InventoryInquiryApiResponseInventoryInquiryApiResult都位于xmlns="http://tempuri.org/"命名空间中,这不是'甚至在样式表中声明。因此,您开始时$__MappingResults变量为空。

AFAICS,这个错误在整个样式表中重复出现,因此您的所有说明都没有选择任何内容。

答案 1 :(得分:1)

您尚未在XSL中声明名称空间“s”。如果你在编辑器中打开XSL并且你有exclude-result-prefixes =“xalan tns s”,那么这已经是一个错误。