开发者

Altova's and Cooktop's different result

I have lookup table from this table we take result if buyeritemcode=substring(field[@id='0'], 11,3) then subfamily=subfamily from lookup table, otherwise '9':

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

Xml file looks:

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

I need to compare this data with lookup.xml and if data not compare insert constant 9. With altova v11 my program works, with cooktop doesn't, I mean comparing is false. My program looks:

<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>
     开发者_如何学Go                               <xsl:value-of select="'9'"/>
                                </xsl:otherwise>
                            </xsl:choose>
                        </SubFamily>
                    </Line-Item>
                </Line>
            </xsl:for-each>
        </PriceCatalogue-Lines>
    </xsl:template>
</xsl:stylesheet>

Correct result which I get with Altova and I want to will get this result with 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>

BAD result which I get with 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>


The problem is in the source XML document:

The CDATA sections contain an unnecessary [ character and it is the first character of the text node. This means that:

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

is always false()

Solution:

Replace:

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

with:

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

Also replace:

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

with

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

Now, regardless of the XSLT processor used (I have 9 of them at home and could run this on 8 of them: MSXML3/4, .NET XslCompiledTransform and XslTransform, AltovaXML, Saxon 6.5.4, Saxon 9.1.05 and XQSharp), the result of the transformation is what I guess you wanted:

<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>

My guess is that Cooktop's XSLT processor needs some configuration in order to be enabled to execute the document() function -- study the available documentation how to do this.


Petras, the output you're seeing could mean the XSLT processor is not able to find the lookup.xml file.

Since you're using a relative URL ('lookup.xml'), do you know what the base URL is? In other words, relative to what?

By default, I believe the base URL used is that of the stylesheet. If you pass a second argument to document(), you can explicitly set the base URL. E.g.:

document('lookup.xml', /)

would look for 'lookup.xml' relative to the input XML file.

You could fix the problem, or at least find out if that is the problem, by providing an absolute URL to 'lookup.xml'. Why don't you try that, and let us know if it worked. E.g.

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

or

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

P.S. XML Cooktop has been a great piece of software, but it seems to be rather old and now apparently unmaintained. This becomes a problem when glitches appear. You might want to try other XSLT tools, like OxygenXML or StylusStudio, that are still maintained.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜