简体   繁体   English

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

[英]Would someone let me know what is wrong with the XSL below?

I created this xslt mapping using Contivo but it's not working for the XML below.我使用 Contivo 创建了这个 xslt 映射,但它不适用于下面的 XML。 Would someone be able to identify what is wrong, please?请问有人能识别出什么问题吗?

I spent some time already working on it but was not able to figure out what is wrong.我已经花了一些时间来研究它,但无法弄清楚出了什么问题。

Here is the XSLT:这是 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>

Here is XML:这是 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>

There could be (and probably are) various things wrong with your XSL.您的 XSL 可能(并且可能)存在各种问题。 The first thing that jumps to the eye ( after removing the undeclared s prefix from the exclude-result-prefixes list) is that you're not using the correct namespaces of the source XML.引起注意的第一件事(exclude-result-prefixes列表中删除未声明的s前缀之后)是您没有使用源 XML 的正确命名空间。

For example, in your very first selection:例如,在您的第一个选择中:

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

you are using the same tns: prefix for all your location steps - but in your XML, both InventoryInquiryApiResponse and InventoryInquiryApiResult are in the xmlns="http://tempuri.org/" namespace, which isn't even declared in your stylesheet.您对所有位置步骤使用相同的tns:前缀 - 但在您的 XML 中, InventoryInquiryApiResponseInventoryInquiryApiResult都在xmlns="http://tempuri.org/"命名空间中,它甚至没有在样式表中声明。 So you are starting off with your $__MappingResults variable being empty.因此,您开始时$__MappingResults变量为空。

AFAICS, this mistake is repeated throughout your stylesheet, so that none of your instructions are selecting anything. AFAICS,这个错误在你的样式表中重复出现,所以你的指令都没有选择任何东西。

You have not declared the namespace "s" in the XSL.您尚未在 XSL 中声明名称空间“s”。 THat is already an error if you open the XSL in an editor and you have exclude-result-prefixes="xalan tns s".如果您在编辑器中打开 XSL 并且您有 exclude-result-prefixes="xalan tns s",那已经是一个错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM