Как преобразовать XML в виде строки без использования файлов в .NET?
Скажем, у меня две строки:
- один - это данные XML
- а другой - данные XSL.
Данные xml и xsl хранятся в столбцах базы данных, если вы должны знать.
Как я могу преобразовать XML в С# без сохранения файлов xml и xsl в качестве файлов? Я хотел бы, чтобы вывод также был строкой (HTML из преобразования).
Кажется, С# предпочитает преобразовывать файлы. Я не смог найти перегрузку ввода-вывода для Load() в XslCompiledTransform. Итак, почему я спрашиваю.
Ответы
Ответ 1
Вот с чем я пошел. Это комбинация ваших ответов. Я голосовал за ответы, которые вдохновили это:
string output = String.Empty;
using (StringReader srt = new StringReader(xslInput)) // xslInput is a string that contains xsl
using (StringReader sri = new StringReader(xmlInput)) // xmlInput is a string that contains xml
{
using (XmlReader xrt = XmlReader.Create(srt))
using (XmlReader xri = XmlReader.Create(sri))
{
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(xrt);
using (StringWriter sw = new StringWriter())
using (XmlWriter xwo = XmlWriter.Create(sw, xslt.OutputSettings)) // use OutputSettings of xsl, so it can be output as HTML
{
xslt.Transform(xri, xwo);
output = sw.ToString();
}
}
}
Примечание: этот оператор требуется в xsl для вывода в виде HTML:
<xsl:output method="html" omit-xml-declaration="yes" />
Ответ 2
Мне потребовалось много времени (буквально годы), чтобы понять, насколько сжатым может быть код Stream
и/или TextWriter
, если вы используете правильные идиомы.
Предполагая, что transform
и input
являются строками:
StringWriter sw = new StringWriter();
using (XmlReader xrt = XmlReader.Create(new StringReader(transform))
using (XmlReader xri = XmlReader.Create(new StringReader(input))
using (XmlWriter xwo = XmlWriter.Create(sw))
{
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(xrt);
xslt.Transform(xri, xwo);
}
string output = sw.ToString();
Ответ 3
Вы можете XmlReader.Create() из StringReader или MemoryStream. XslCompileTransfrom может Загрузить() из XmlReader.
Ответ 4
edit: добавлены дополнительные блокировки
// input-xml
string xmlinput = String.Empty;
// xslt
string xsltinput = String.Empty;
// output-xml
string xmloutput = String.Empty;
// Prepare input-xml
XPathDocument doc = new XPathDocument(new StringReader(xmlinput));
// Prepare XSLT
XslTransform xslt = new XslTransform();
// Creates a XmlReader from your xsl string
using (XmlReader xmlreader = XmlReader.Create(new StringReader(xsltinput)))
{
//Load the stylesheet.
xslt.Load(xmlreader);
// transform
using (StringWriter sw = new StringWriter())
{
xslt.Transform(doc, null, sw);
// save to string
xmloutput = sw.ToString();
}
}
Ответ 5
Я отправляю xml-контент, а затем загружаю XSLT-документ, применяю преобразование и возвращаю новый xml.
public static string Transform(string xmlString)
{
string output = String.Empty;
try
{
// Load an XML string into the XPathDocument.
StringReader rdr = new StringReader(xmlString);
XPathDocument myXPathDoc = new XPathDocument(rdr);
var myXslTrans = new XslTransform();
//load the Xsl
myXslTrans.Load("XSLTFile.xslt");
//create the output stream
StringWriter sw = new StringWriter();
XmlWriter xwo = XmlWriter.Create(sw);
//do the actual transform of Xml
myXslTrans.Transform(myXPathDoc, null, xwo);
output = sw.ToString();
xwo.Close();
return output;
}
catch (Exception e)
{
Console.WriteLine("Exception: {0}", e.ToString());
throw;
}
}
ПРИМЕЧАНИЕ: "XSLTFile.xslt" Он добавляется в решение и устанавливает для свойства "Копировать в выходной каталог" значение "Копировать всегда".
Ответ 6
Версия VB.Net, вдохновленная ответом Роберта Россни:
Private Function TransformXML(XMLPath As String, XSLPath As String) As String
Dim XSLT As XslCompiledTransform = New XslCompiledTransform()
Dim sWriter As StringWriter = New StringWriter
Dim xReader As XmlReader = XmlReader.Create(XMLPath)
Using xWriter As XmlWriter = XmlWriter.Create(sWriter)
XSLT.Load(XSLPath)
XSLT.Transform(xReader, xWriter)
End Using
Return sWriter.ToString
End Function
Ответ 7
Я бы использовал перегрузки XmlReader.Create(DatabaseBlobStream)
и XmlWriter.Create(StringBuilder)
. Использование следующего объекта DatabaseBlobStream
DatabaseBlobStream.cs
internal class DatabaseBlobStream : Stream
{
private readonly IDataReader reader;
private readonly int columnIndex;
private long streamPosition;
internal DatabaseBlobStream(IDataReader reader, int columnIndex)
{
this.reader = reader;
this.columnIndex = columnIndex;
}
public override bool CanRead
{
get
{
return reader.GetFieldType(columnIndex) == typeof (byte[])
&& !reader.IsDBNull(columnIndex);
}
}
public override bool CanSeek
{
get { return false; }
}
public override bool CanWrite
{
get { return false; }
}
public override void Flush()
{
throw new Exception("This stream does not support writing.");
}
public override long Length
{
get { throw new Exception("This stream does not support the Length property."); }
}
public override long Position
{
get
{
return streamPosition;
}
set
{
streamPosition = value;
}
}
public override int Read(byte[] buffer, int offset, int count)
{
if (reader.IsDBNull(columnIndex))
return 0;
int bytesRead = (int)reader.GetBytes(columnIndex, streamPosition + offset, buffer, 0, count);
streamPosition += bytesRead;
return bytesRead;
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new Exception("This stream does not support seeking.");
}
public override void SetLength(long value)
{
throw new Exception("This stream does not support setting the Length.");
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new Exception("This stream does not support writing.");
}
public override void Close()
{
try
{
reader.Close();
}
finally
{
base.Close();
}
}
protected override void Dispose(bool disposing)
{
try
{
reader.Dispose();
}
finally
{
base.Dispose(disposing);
}
}
}