2015-09-21 22 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