我在C#中有以下一些代码,用于使用XSLT /
将XML文件转换为另一个string xmlInput = @"<?xml version='1.0' encoding='UTF-8'?><catalog><cd><title> Empire Burlesque </title ><artist> Bob Dylan </artist><country> USA </country><company> Columbia </company><price> 10.90 </price><year> 1985 </year></cd></catalog>";
///////////////////////////////////////////////////////////////
string xmlOutput = String.Empty;
using (StringReader sri = new StringReader(xmlInput))
{
using (XmlReader xri = XmlReader.Create(sri))
{
XslCompiledTransform xslt = new XslCompiledTransform();
//xslt.Load(xrt);
xslt.Load(@"XSLT/slide2.xslt");
using (StringWriter sw = new StringWriter())
using (XmlWriter xwo = XmlWriter.Create(sw, new XmlWriterSettings { Encoding = Encoding.UTF8 }))
{
xslt.Transform(xri, xwo);
xmlOutput = sw.ToString();
}
}
}
xmlOutput给了我"<?xml version=\"1.0\" encoding=\"utf-16\"?><root> Empire Burlesque </root>"
我怎么能得到utf-8而没有斜线?
答案 0 :(得分:0)
.NET字符串是UTF-16编码字符的序列,StringWriter / StringBuilder默认为该编码。 (来源https://forums.asp.net/post/3240311.aspx)
所以你需要创建一个继承默认字符串编写器的类:
public class StringWriterWithEncoding : StringWriter
{
Encoding myEncoding;
public override Encoding Encoding
{
get
{
return myEncoding;
}
}
public StringWriterWithEncoding(Encoding encoding) : base()
{
myEncoding = encoding;
}
public StringWriterWithEncoding(Encoding encoding) : base(CultureInfo.CurrentCulture)
{
myEncoding = encoding;
}
public StringWriterWithEncoding(StringBuilder sb, Encoding encoding) : base(sb, CultureInfo.CurrentCulture)
{
myEncoding = encoding;
}
}
并创建一个实例,例如StringWriterWithEncoding utf8Writer = new StringWriterWithEncoding(Encoding.UTF8);并将其作为XslCompiledTransform的Transform方法的第三个参数传递。
像这样使用:
StringBuilder sb = new StringBuilder();
using (StringWriterWithEncoding sw = new StringWriterWithEncoding(sb, Encoding.UTF8))
{
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(@"XSLT/slide2.xslt");
xslt.Transform(xri, sw);
}
xmlOutput = sb.ToString();
答案 1 :(得分:0)
第一个问题是由StringWriter
引起的using (StringWriter sw = new StringWriter())
using (XmlWriter xwo = XmlWriter.Create(sw, new XmlWriterSettings { Encoding = Encoding.UTF8 }))
即使您专门将XmlWriterSettings.Encoding设置为UTF-8,也要将输出流指定为StringWriter,并且由于.NET字符串为UTF-16,因此XmlWriter必须使用UTF-16。 如果您使用例如FileStream而不是StringWriter,则输出将采用UTF-8或您指定的任何编码。
斜杠问题只是你的IDE逃避它。如果您将xmlOutput打印到Console,您将看到它不包含额外的斜杠。
答案 2 :(得分:0)
您可以在XSLT样式表中包含此行:
<xsl:output encoding="utf-8"/>
(或者当然是您喜欢的编码),它会自动将输出设置设置为utf-8编码。
答案 3 :(得分:0)
我相信使用MemoryStream是处理此问题的更好方法。 .net字符串在内部是utf-16,这是在您写入StringBuilder对象的StringWriter时对它们进行编码的方式。使用内存流,可以避免这种陷阱。
string xmlDoc = "";
// Use a memory stream to avoid the .net internal string utf-16 encoding pitfall.
using (MemoryStream xmlStream = new MemoryStream())
using (XmlReader xmlReader = XmlReader.Create(new StringReader(xmlAsText)))
using (XmlReader xsltReader = XmlReader.Create(new StringReader(xsltAsText)))
{
// Transform XML string to new XML based on the XSLT
// Load the XSLT and transform source XML to target XML
XslCompiledTransform myXslTrans = new XslCompiledTransform();
myXslTrans.Load(xsltReader);
myXslTrans.Transform(xmlReader, null, xmlStream);
// Using the encoding from the xslt, transform the xml stream bytes to the xml string.
// If no encoding in xslt, defaults to UTF-8.
xmlDoc = myXslTrans.OutputSettings.Encoding.GetString(xmlStream.ToArray());
// Remove the BOM if it exists
string byteOrderMark = myXslTrans.OutputSettings.Encoding.GetString(myXslTrans.OutputSettings.Encoding.GetPreamble());
if (xmlDoc.StartsWith(byteOrderMark, StringComparison.Ordinal))
{
xmlDoc = xmlDoc.Remove(0, byteOrderMark.Length);
}
}
如果样式表中没有编码属性,则默认情况下您将获得UTF-8,而不是UTF-16。这与将其直接写入文件一样。抱歉,我无法说说它如何在不同的文化中发挥作用。
我建议使用这种方法,而不要使用其他方法对UTF-8进行硬编码。可以使用样式表中的任何(有效)编码,例如ISO-8859-1。