2013-05-01 84 views
1

我是xslt的新手,我需要使用xslt將兩個xml合併爲一個。作爲初始練習,我創建了三個文件file1.xml,file2.xml和transform.xslt,並找出如何通過直接運行file1.xml來合併這些文件。這是我做的:在ASP.NET中使用xslt合併兩個xml文件

在file1.xml:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<?xml-stylesheet type="text/xsl" href="transform.xslt"?> 
<stuff> 
    ... 
</stuff> 

在file2.xml:

<morestuff> 
    ... 
</morestuff> 

在transform.xslt:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:custom="custom-functions"> 
    <xsl:output method="xml" indent="yes" version="1.0" encoding="ISO-8859-1"/> 
    <xsl:variable name="file2" select="document('file2.xml')" /> 
    <xsl:doing-stuff> 
     ... 
     <!-- contains references to $file2 --> 
     ... 
    </xsl:doing-stuff> 
</xsl:stylesheet> 

但我需要能夠通過我的C#ASP.NET代碼完成此操作,並使用給定的xml 字符串代替xml 檔案。像這樣:

public string MergeXmls(string xml1, string xml2){ 
    string mergedXml; 
    var xsltPath = HttpContext.Current.Server.MapPath("transform.xslt"); 
    //??? 
    return mergedXml; 
} 

我該如何做到這一點?我知道我需要從transform.xslt中刪除對document('file2.xml')的引用,但我不知道該從哪裏去。

回答

1

這可以使用XmlPreloadedResolver類來完成。這允許您預載將用於解析XSLT中的document函數的實體。

唯一要注意的是,URI在document函數中指定的被視爲相對於XSLT文檔本身的基URI,所以你必須通過XmlReader使用稍微迴旋方法來加載,以便可以覆蓋基本URI。

public string MergeXml(string xml1, string xml2) 
{ 
    XslCompiledTransform xslt = new XslCompiledTransform(); 
    XmlDocument xsltDoc = new XmlDocument(); 
    // Load the XSLT file through XmlReader to override the base URI. 
    using(StreamReader reader = File.OpenText(HttpContext.Current.Server.MapPath("transform.xslt"))) 
    using(XmlReader xmlReader = XmlReader.Create(reader, null, "file:///transform.xslt")) 
    { 
     xsltDoc.Load(xmlReader); 
    } 
    // Use XsltSettings to enable the use of the document() function. 
    xslt.Load(xsltDoc, new XsltSettings(true, false), null); 

    // Load the first XML file into a document 
    XmlDocument doc = new XmlDocument(); 
    doc.LoadXml(xml1); 

    // Create the resolver and add the second file to it. 
    XmlPreloadedResolver resolver = new XmlPreloadedResolver(); 
    resolver.Add(new Uri("file:///file2.xml"), xml2); 

    using(StringWriter writer = new StringWriter()) 
    using(XmlWriter xmlWriter = XmlWriter.Create(writer)) 
    { 
     // Pass the resolver to the transform 
     xslt.Transform(doc, null, xmlWriter, resolver); 
     return writer.ToString(); 
    } 
} 

XmlPreloadedResolver類僅在.NET 4.0和更高版本中提供,但如果您使用的是較早的版本,你仍然可以從System.Xml.XmlResolver派生的自定義類,並自己實現類似的功能。

+0

我正在使用.Net 4.0,這完美地工作!謝謝! – Kalina 2013-05-02 16:10:28

1

在前端網頁我用一個System.Web.UI.WebControls.Xml對象是這樣的:

<asp:Xml ID="xmlDisplay" runat="server" /> 

在我身後的功能的代碼會是這樣的:

public void MergeXmls(string xml1, string xml2) 
{ 
    string mergedXml = "<root>" + xml1 + xml2 + "</root>; 
    xmlDisplay.DocumentContent = mergedXml; 
    xmlDisplay.TransformSource = Server.MapPath("transform.xslt"); 
} 

加載頁面時,xmlDisplay對象將保存從在mergedXml中找到的XML字符串中將數據加載到XSLT中的結果。

此處提供的代碼示例沒有解決從作爲參數傳遞的2個字符串中創建有效的XML字符串,它只是連接了2個可能在某些情況下可行的字符串。

然後應該調整您的XSLT,以便XPath到數據元素與到mergedXml字符串中找到的元素的路徑匹配。 XSLT不會引用源XML數據文件。

希望有所幫助。

+0

謝謝,但我的意思是通過在[本示例]中匹配id來使用xslt合併它們(http://stackoverflow.com/questions/1510688/xslt-a-simple-way-to-merge-xml-files ),而不僅僅是將一個追加到另一個,然後_then_進行xsl轉換。 – Kalina 2013-05-02 16:05:03