2015-09-21 90 views
1

我正在尝试使用Delphi XE8执行XSLT转换,并遇到问题。我的XSL文件引用外部XSL文件,使用一个其声明href属性具有相对路径的import语句。转换失败并显示错误“命名模板'skrivUtDate'没有出现在样式表中。”定义'skrivUtDate'位于外部XSL文件中。定义如下所示:使用Delphi XE8进行XSLT转换的替代方案

<xsl:template name="skrivUtDate"> 
    <xsl:param name="oppgittTid"/> 
    <xsl:if test="string-length($oppgittTid)!=0"> 
     <xsl:value-of select="substring($oppgittTid,9,2)"/>.<xsl:value-of select="substring($oppgittTid,6,2)"/>.<xsl:value-of select="substring($oppgittTid,3,2)"/> 
    </xsl:if> 
</xsl:template> 

我已经把外部XSL文件中的相应目录(相对于原来的XSL文件),但我得到同样的错误(我也尝试过其他所有可能的目录本外部文件,但没有任何工作)。但是,我可以使用EditX XML Editor来执行转换,所以我不认为这个XSL是无效的(请注意,这个XSL文件是由第三方提供的,显然它被一些使用开发平台的人成功地使用了德尔福)。

下面是XSL文件的开头片段:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" 
    xmlns:ref="http://www.kith.no/xmlstds/henvisning/2012-02-15" 
    xmlns:xhtml="http://www.w3.org/1999/xhtml" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:po="http://www.kith.no/xmlstds/po/poKomponent/2009-06-30" 
    xmlns:fk1="http://www.kith.no/xmlstds/felleskomponent1" 
    exclude-result-prefixes="ref xhtml po fk1"> 
    <xsl:import href="../../Felleskomponenter/funksjoner.xsl"/> 

而且,是的,funksjoner.xsl文件是在一个名为Felleskomponenter目录。

我非常简单的测试使用类似于下面的伪代码的东西:

var 
    XML : IXMLDocument; 
    XSL : IXMLDocument; 
    s: WideString; 
begin 
    XML := TXMLDocument.Create(self); 
    XML.FileName := 'C:\somepath\some.xml'; 
    XML.Active := True; 
    XSL := TXMLDocument.Create(Self); 
    XSL.FileName := 'C:\someotherpath\somefile.xsl'; 
    XSL.Active := True; 
    XML.DocumentElement.TransformNode(XSL.DocumentElement, s); 

我知道德尔福XE7开始全方位XML DOM还有ADOM出货,但这些显然不存在从德尔福XE8 。我希望使用不同的文档对象模型可以解决这个问题。

与XSL一样,XML非常复杂。

有没有任何机构对使用Delphi XE8执行XSLT转换的替代方法有任何建议?

+0

MSXML似乎无法处理导入文件的相对路径的多个元素层(有3个级别,第2级导入2个,尽管这些文件与文件所在的目录相同他们正在进口)。DIXML能够正确地解析XSL文件,并且它很容易使用,但是转换返回了一个AnsiString,导致一些Unicode字符被破坏。我在这里发布了一个关于DIXML的新问题:http://stackoverflow.com/questions/32760579/does-dixml-for-delphi-support-unicode-in-xstl-transformations –

回答

2

为了使XSLT在Delphi中正常工作,您需要使用MSXML加载XML和XSL文件。这篇文章给出了n example on how to use MSXML with DelphiTransformNode使用MSXML。沿着以下

的东西应该工作(采取from here,不完整的片段):

var 
    xmlEmployees, xslStyle : IXMLDOMDocument; 
begin 
    xmlEmployees := CoDOMDocument.Create; 
    xslStyle  := CoDOMDocument.Create; 
    xmlEmployees.load('employees.xml'); 
    xslStyle.load('empuksna.xsl'); 
    result := xmlEmployees.transformNode(xslStyle); 
end; 

同样的,如果你是通过一个字符串来加载XML和XSL,原来的位置丢失。大多数处理器都支持设置基本uri,但看起来像IXSLProcessor没有这样的选项。


您还需要一个替代方案。 DIXML支持libxslt,它在某些方面优于MSXML(尽管不适用于.NET的XSLT,如果您喜欢使用.NET进行互操作,这也是另一种选择)。 The package of DIXML附带演示文件夹中的一堆演示和示例。

如果你可以切换到.NET,this (rather old) DrDobb's article shows how to do XSLT with .NET and Delphi,也显示了又一个变换另一种选择(虽然它承担的Delphi 7,不知道它仍然适用)。

+0

谢谢你的慷慨投入。我还没有这个工作 - 即使EditX XML编辑器可以执行转换,我仍然在Delphi中遇到错误。我会报告我的进展。 –

+0

@CaryJensen,如果您使用的是现代Windows计算机,则可能安装的MSXML版本不是您尝试加载的版本。如果COM操作失败,请尝试[下载MSXML](http://www.microsoft.com/en-us/download/details.aspx?id=3988)(通常为版本3.0或6.0或其他版本)是有问题的) – Abel

+0

@CaryJensen,你可以用['XmlVersion.exe'或'Versions.exe'](https://support.microsoft.com/en-us/kb/278674)检查已安装的版本 – Abel