Altova 和 Cooktop 的不同结果
我有来自该表的查找表,如果 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题出在源 XML 文档中:
CDATA 部分包含不必要的
[
字符,并且它是文本节点的第一个字符。这意味着:始终是
false()
解决方案:
替换:
替换为:
同时替换:
with
现在,无论使用什么 XSLT 处理器(我家里有 9 个,可以在其中 8 个上运行:MSXML3/4、.NET XslCompiledTransform 和 XslTransform、AltovaXML 、Saxon 6.5.4、Saxon 9.1.05 和 XQSharp),转换的结果就是我猜你想要的:
我的猜测是 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:is always
false()
Solution:
Replace:
with:
Also replace:
with
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:
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,您看到的输出可能意味着 XSLT 处理器无法找到lookup.xml 文件。
由于您使用的是相对 URL(“lookup.xml”),您知道基本 URL 是什么吗?换句话说,相对于什么?
默认情况下,我相信使用的基本 URL 是样式表的 URL。如果将第二个参数传递给 document(),则可以显式设置基本 URL。例如:
将查找相对于输入 XML 文件的“lookup.xml”。
您可以通过提供“lookup.xml”的绝对 URL 来解决该问题,或者至少查明这是否是问题所在。您为什么不尝试一下,让我们知道它是否有效。例如
或
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.:
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.
or
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.