在ASP.NET中使用xslt合并两个xml文件

本文关键字:两个 文件 xml 合并 NET ASP xslt | 更新日期: 2023-09-27 18:11:57

我是xslt新手,我需要使用xslt将两个xml合并为一个xml。作为最初的练习,我创建了三个文件:file1.xml、file2.xml和transform。Xslt,并弄清楚如何通过直接运行file1.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>

在变换。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;
}

我该怎么做?我知道我需要从变换中删除对document('file2.xml')的引用。

在ASP.NET中使用xslt合并两个xml文件

这可以使用XmlPreloadedResolver类来完成。这允许您预加载将用于解析XSLT中的document函数的实体。

唯一需要注意的是,在document函数中指定的URI被视为相对于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中派生一个自定义类,并自己实现类似的功能。

在前端网页上,我使用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的结果。

这里提供的代码示例不涉及从作为参数传递的两个字符串中创建一个有效的XML字符串,它只是将两个字符串连接起来,这在某些情况下可能有效。

然后应该调整XSLT,使数据元素的xpath与在mergedXml字符串中找到的元素的路径匹配。XSLT将没有对源XML数据文件的引用。

希望对你有帮助。