C#向XSLT转换器传入多个内存XML文件提示文档加载错误如何解决
问题根源
报错是两个核心不匹配导致的:
- 你的XSLT中
audioxml参数默认值是./audio.xml,转换时会尝试加载这个URI对应的资源 - 你在
XmlPreloadedResolver中仅注册了file:///file2.xml对应的内容,没有和XSLT的参数关联,也没有覆盖默认的audio.xml路径
解决步骤
第一步:新增XSLT参数传递逻辑
创建XsltArgumentList对象,将audioxml参数的值设置为你注册到XmlPreloadedResolver中的URI,保证资源路径完全匹配。
第二步:修正资源注册逻辑(可选但建议)
直接将XML字符串转为UTF8字节数组注册,避免编码解析异常。
最终可运行代码
public static string MergeXml(string xml1, string xml2) { XslCompiledTransform xslt = new XslCompiledTransform(); XmlDocument xsltDoc = new XmlDocument(); // 加载XSLT模板 using (StreamReader reader = File.OpenText(@"template.xsl")) using (XmlReader xmlReader = XmlReader.Create(reader, null, "file:///template.xsl")) { xsltDoc.Load(xmlReader); } // 允许使用document()函数 xslt.Load(xsltDoc, new XsltSettings(true, false), null); // 加载主XML(book.xml内容) XmlDocument doc = new XmlDocument(); doc.LoadXml(xml1); // 注册内存XML到解析器,URI和后续传参保持一致 XmlPreloadedResolver resolver = new XmlPreloadedResolver(); byte[] audioXmlBytes = System.Text.Encoding.UTF8.GetBytes(xml2); resolver.Add(new Uri("file:///audio.xml"), audioXmlBytes); // 传递XSLT参数,指定audioxml的路径为预注册的URI XsltArgumentList args = new XsltArgumentList(); args.AddParam("audioxml", "", "file:///audio.xml"); using (StringWriter writer = new StringWriter()) using (XmlWriter xmlWriter = XmlWriter.Create(writer)) { // 转换时传入参数列表 xslt.Transform(doc, args, xmlWriter, resolver); return writer.ToString(); } }
更优的无document()方案(推荐)
如果不想依赖document()函数和资源解析器,可以直接将内存XML作为节点参数传入XSLT,性能更好也更易排查问题:
- 修改XSLT定义,替换原来的param和variable配置:
<!-- 替换原有两行配置 --> <xsl:param name="audiofile" />
- C#代码中直接传入节点参数,不需要配置
XmlPreloadedResolver:
// 加载audio XML为XmlNode XmlDocument audioDoc = new XmlDocument(); audioDoc.LoadXml(xml2); // 直接传入节点参数 XsltArgumentList args = new XsltArgumentList(); args.AddParam("audiofile", "", audioDoc.DocumentElement);
内容的提问来源于stack exchange,提问作者j4rey
相关产品推荐
相关产品推荐

