I am trying to convert the following xslt to reference an in-memory 'audio' xml file instead of the physical audio.xml
file.
The following xslt file works with the physical xml files.
<?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:param name="audioxml" select="'./audio.xml'"/>
<xsl:variable name="audiofile" select="document($audioxml)"/>
<xsl:template match="/">
<xsl:for-each select="bookstore" >
<xsl:for-each select="book" >
<booktitle>
<xsl:value-of select="title" />
</booktitle>
</xsl:for-each>
</xsl:for-each>
<xsl:for-each select="$audiofile">
<xsl:for-each select="audiostore" >
<xsl:for-each select="audio" >
<audiotitle>
<xsl:value-of select="title" />
</audiotitle>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
book.xml
<?xml version=\"1.0\" encoding=\"utf-8\" ?><bookstore><book genre=\"autobiography\" publicationdate=\"1981\" ISBN=\"1-861003-11-0\"><title>The Autobiography of Benjamin Franklin</title><author><first-name>Benjamin</first-name><last-name>Franklin</last-name></author><price>8.99</price></book></bookstore>
audio.xml
<?xml version=\"1.0\" encoding=\"utf-8\" ?><audiostore><audio genre=\"autobiography\" publicationdate=\"1981\" ISBN=\"1-861003-11-0\"><title>The Autobiography of Benjamin Franklin 2</title><author><first-name>Benjamin 2</first-name><last-name>Franklin 2</last-name></author><price>8.99</price></audio></audiostore>
So I am trying to pass the xml files in-memory but the following code is complaining that An error occurred while loading document '/file2.xml'
public static 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(@"template.xsl"))
using (XmlReader xmlReader = XmlReader.Create(reader, null, "file:///template.xsl"))
{
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();
}
}
CodePudding user response:
It seems, the Add
method of the XmlPreloadedResolver, when taking a string, parses it as UTF-16/Encoding.Unicode in .NET so either don't put any XML declaration on the strings you pass to the Add
method or make sure they declare UTF-16 e.g. var xml2 = "<?xml version=\"1.0\" encoding=\"utf-16\" ?><audiostore>...