我使用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], "")"/>
</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 > 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 = ' ' or $char = '	' or $char = '
' or $char = '
'"/>
</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 <= $len) and ($index <= 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 >= 1) and ($len - $index <= 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>
答案 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中,InventoryInquiryApiResponse
和InventoryInquiryApiResult
都位于xmlns="http://tempuri.org/"
命名空间中,这不是'甚至在样式表中声明。因此,您开始时$__MappingResults
变量为空。
AFAICS,这个错误在整个样式表中重复出现,因此您的所有说明都没有选择任何内容。
答案 1 :(得分:1)
您尚未在XSL中声明名称空间“s”。如果你在编辑器中打开XSL并且你有exclude-result-prefixes =“xalan tns s”,那么这已经是一个错误。