Altova 和 Cooktop 的不同结果

发布于 2024-11-06 15:51:31 字数 4985 浏览 1 评论 0原文

我有来自该表的查找表,如果 buyitemcode=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>

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

jJeQQOZ5 2024-11-13 15:51:31

问题出在源 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>

with

<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() 函数——研究可用的文档如何做到这一点。

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.

银河中√捞星星 2024-11-13 15:51:31

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

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

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

document('lookup.xml', /)

将查找相对于输入 XML 文件的“lookup.xml”。

您可以通过提供“lookup.xml”的绝对 URL 来解决该问题,或者至少查明这是否是问题所在。您为什么不尝试一下,让我们知道它是否有效。例如

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

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

P.S. XML Cooktop 是一个很棒的软件,但它似乎相当老旧,而且现在显然没有维护。当出现故障时,这就会成为一个问题。您可能想尝试其他仍在维护的 XSLT 工具,例如 OxygenXML 或 StylusStudio。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文