Altova和Cooktop的结果不同

时间:2011-05-11 14:37:34

标签: xslt

我有来自这个表的查找表,如果buyeritemcode = substring(field [@ id ='0'],11,3),那么subfamily =查询表中的subfamily,否则为'9':

<lookup>
    <Code>
        <BuyerItemCode>439</BuyerItemCode>
        <Subfamily>016</Subfamily>          
    </Code>
</lookup>   

Xml文件看起来:

<document>
    <line id="14">
        <field id="0"><![CDATA[MMM4443 419280600000]]></field>
    </line>
    <line id="15">
        <field id="0"><![CDATA[MMM4443 414390600000]]></field>
    </line>
</document>

我需要将这些数据与lookup.xml进行比较,如果数据不比较插入常量9.使用altova v11,我的程序可以工作,而cooktop不行,我的意思是比较是假的。 我的程序看起来:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:date="http://exslt.org/dates-and-times" xmlns:exsl="http://exslt.org/common" extension-element-prefixes="date exsl">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:key name="ProdSubfamily" match="Subfamily" use="../BuyerItemCode"/>
    <xsl:template match="/">
        <Interchange>
            <Group>
                <Message>
                    <xsl:if test="/document/line[(substring(field[@id='0'], 1,3)='MMM')]">
                        <xsl:apply-templates mode="MMM" select="/document"/>
                    </xsl:if>
                </Message>
            </Group>
        </Interchange>
    </xsl:template>
    <xsl:template mode="MMM" match="/document">
        <PriceCatalogue-Lines>
            <xsl:for-each select="/document/line[contains(substring(field[@id='0'], 1,3),'MMM') and not(contains(substring(field[@id='0'],9,1),'0'))]">
                <xsl:variable name="inputProd" select="substring(field[@id='0'], 11,3)"/>
                <Line>
                    <Line-Item>
                        <LineNumber>
                            <xsl:value-of select="position()"/>
                        </LineNumber>
                        <BuyerItemCode>
                            <xsl:value-of select="substring(field[@id='0'], 11,3)"/>
                        </BuyerItemCode>
                        <SubFamily>
                            <xsl:choose>
                                <xsl:when test="substring(field[@id='0'], 11,3) = document('lookup.xml')/*/*/BuyerItemCode">
                                    <xsl:for-each select="document('lookup.xml')">
                                        <xsl:for-each select="key('ProdSubfamily',$inputProd)">
                                            <xsl:value-of select="."/>
                                        </xsl:for-each>
                                    </xsl:for-each>
                                </xsl:when>
                                <xsl:otherwise>
                                    <xsl:value-of select="'9'"/>
                                </xsl:otherwise>
                            </xsl:choose>
                        </SubFamily>
                    </Line-Item>
                </Line>
            </xsl:for-each>
        </PriceCatalogue-Lines>
    </xsl:template>
</xsl:stylesheet>

我用Altova得到的结果正确,我想用cooktop得到这个结果:

<Interchange>
    <Group>
        <Message>
            <PriceCatalogue-Lines>
                <Line>
                    <Line-Item>
                        <LineNumber>1</LineNumber>
                        <BuyerItemCode>928</BuyerItemCode>
                        <SubFamily>9</SubFamily>
                    </Line-Item>
                </Line>
                <Line>
                    <Line-Item>
                        <LineNumber>2</LineNumber>
                        <BuyerItemCode>439</BuyerItemCode>
                        <SubFamily>016</SubFamily>
                    </Line-Item>
                </Line>
            </PriceCatalogue-Lines>
        </Message>
    </Group>
</Interchange>

我用Cooktop得到的坏结果:

<Interchange>
<Group>
<Message>
<PriceCatalogue-Lines>
<Line>
<Line-Item>
<LineNumber>1</LineNumber>
<BuyerItemCode>928</BuyerItemCode>
<SubFamily>9</SubFamily>
</Line-Item>
</Line>
<Line>
<Line-Item>
<LineNumber>2</LineNumber>
<BuyerItemCode>439</BuyerItemCode>
<SubFamily>9</SubFamily>
</Line-Item>
</Line>
</PriceCatalogue-Lines>
</Message>
</Group>
</Interchange>

2 个答案:

答案 0 :(得分:1)

问题出在源XML文档

CDATA部分包含不必要的[字符,它是文本节点的第一个字符。这意味着:

substring(field[@id='0'], 1,3)='MMM'

总是false()

<强>解决方案

<强>替换

<field id="0"><![CDATA[[MMM4443 419280600000]]></field>

<强>与

<field id="0"><![CDATA[MMM4443 419280600000]]></field>

同时替换

<field id="0"><![CDATA[[MMM4443 414390600000]]></field>

<强>与

<field id="0"><![CDATA[MMM4443 414390600000]]></field>

现在,无论使用何种XSLT处理器(我家中有9个处理器,可以在其中8个处理器运行:MSXML3 / 4,.NET XslCompiledTransform和XslTransform,AltovaXML,Saxon 6.5.4,Saxon 9.1 .05和XQSharp),转换的结果就是我想你想要的

<Interchange>
  <Group>
    <Message>
      <PriceCatalogue-Lines>
        <Line>
          <Line-Item>
            <LineNumber>1</LineNumber>
            <BuyerItemCode>928</BuyerItemCode>
            <SubFamily>9</SubFamily>
          </Line-Item>
        </Line>
        <Line>
          <Line-Item>
            <LineNumber>2</LineNumber>
            <BuyerItemCode>439</BuyerItemCode>
            <SubFamily>016</SubFamily>
          </Line-Item>
        </Line>
      </PriceCatalogue-Lines>
    </Message>
  </Group>
</Interchange>

我的猜测是,Cooktop的XSLT处理器需要一些配置才能启用document()功能 - 请参阅可用文档,了解如何执行此操作。

答案 1 :(得分:0)

Petras,您看到的输出可能意味着XSLT处理器无法找到lookup.xml文件。

由于您使用的是相对URL('lookup.xml'),您知道基本URL是什么吗?换句话说,相对于什么?

默认情况下,我认为使用的基本URL是样式表的基本URL。如果将第二个参数传递给document(),则可以显式设置基本URL。 E.g:

document('lookup.xml', /)

会查找相对于输入XML文件的'lookup.xml'。

您可以通过提供“lookup.xml”的绝对URL来解决问题,或者至少找出是否问题。你为什么不尝试这个,让我们知道它是否有效。 E.g。

document('/home/lars/lookup.xml')

document('file:///c:/temp/lookup.xml')

P.S。 XML Cooktop是一款非常棒的软件,但它似乎相当陈旧,现在显然没有维护。出现毛刺时,这会成为问题。您可能想尝试其他仍在维护的XSLT工具,如OxygenXML或StylusStudio。