【问题标题】:How to create an XML document from a .NET object?如何从 .NET 对象创建 XML 文档?
【发布时间】:2010-03-30 21:02:28
【问题描述】:

我有以下接受文件名的变量:

var xtr = new XmlTextReader(xmlFileName) { WhitespaceHandling = WhitespaceHandling.None };
var xd = new XmlDocument();
xd.Load(xtr);

我想更改它以便可以传入一个对象。我不想先将对象序列化到文件中。

这可能吗?

更新:

我的初衷是取一个xml文档,合并一些xslt(存储在一个文件中),然后输出返回html……像这样:

public string TransformXml(string xmlFileName, string xslFileName)
{
     var xtr = new XmlTextReader(xmlFileName) { WhitespaceHandling = WhitespaceHandling.None };
     var xd = new XmlDocument();
     xd.Load(xtr);

     var xslt = new System.Xml.Xsl.XslCompiledTransform();
     xslt.Load(xslFileName);
     var stm = new MemoryStream();
     xslt.Transform(xd, null, stm);
     stm.Position = 1;
     var sr = new StreamReader(stm);
     xtr.Close();
     return sr.ReadToEnd();
}

在上面的代码中,我正在从文件中读取 xml。现在我想做的只是在对象被序列化到文件之前使用它。

让我用代码来说明我的问题

public string TransformXMLFromObject(myObjType myobj , string xsltFileName)
{
     // Notice the xslt stays the same.
     // Its in these next few lines that I can't figure out how to load the xml document (xd) from an object, and not from a file....

     var xtr = new XmlTextReader(xmlFileName) { WhitespaceHandling = WhitespaceHandling.None };
     var xd = new XmlDocument();
     xd.Load(xtr);
}

【问题讨论】:

  • 我没有按照你的想法去做,你能发布一个更好的例子吗?
  • 更改what 以便您可以传入一个对象? XmlTextReader?要将对象传递给 XmlTextReader?你希望得到什么
  • @JL:你不应该使用new XmlTextReader()。你应该改用XmlReader.Create()
  • @Cheeso,我想从一个对象而不是文件中加载 xd(XMLDocument),XMLTextReader 对我来说并不重要。
  • @John,为什么新的 XMLTestReader 不好?

标签: c# .net xml


【解决方案1】:

您想将任意 .NET 对象转换为序列化的 XML 字符串吗?没有比这更简单的了!! :-)

public string SerializeToXml(object input)
{
   XmlSerializer ser = new XmlSerializer(input.GetType(), "http://schemas.yournamespace.com");
   string result = string.Empty;

   using(MemoryStream memStm = new MemoryStream())
   {
     ser.Serialize(memStm, input);

     memStm.Position = 0;
     result = new StreamReader(memStm).ReadToEnd();
   } 

   return result;
} 

应该这样 :-) 当然,您也可能希望将默认 XML 命名空间配置为参数。

或者您希望能够在现有对象之上创建 XmlDocument?

public XmlDocument SerializeToXmlDocument(object input)
{
   XmlSerializer ser = new XmlSerializer(input.GetType(), "http://schemas.yournamespace.com");

   XmlDocument xd = null;

   using(MemoryStream memStm = new MemoryStream())
   {
     ser.Serialize(memStm, input);

     memStm.Position = 0;

     XmlReaderSettings settings = new XmlReaderSettings();
     settings.IgnoreWhitespace = true;

     using(var xtr = XmlReader.Create(memStm, settings))
     {  
        xd = new XmlDocument();
        xd.Load(xtr);
     }
   }

   return xd;
}

【讨论】:

  • @marc_s:哎呀!没有using 块! new XmlTextReader()! -1!
  • @John:我只是在修复new XmlTextReader()....你投反对票的速度太快了......
  • @John:但请用简单易懂的语言向我解释XmlReader.Create()new XmlTextReader() 的优势 - 到目前为止,没有人提出令人信服的观点.....
  • @marc_s,引用自文档:Although the Microsoft .NET Framework includes concrete implementations of the XmlReader class, such as the XmlTextReader, XmlNodeReader, and the XmlValidatingReader classes, in the .NET Framework version 2.0, we recommend that you create XmlReader instances using the Create method (msdn.microsoft.com/en-us/library/9khb6435.aspx)。我想唯一令人信服的原因可能是,如果在 .NET 7.9 中引入 HyperXmlReader 类,您无需更改代码即可从中受益:-)
  • @marc_s:在您的第二段代码中,它不会改变任何内容。但是在第一个中,您返回的是一个字符串,因此使用 MemoryStream 然后使用 StreamReader 读取它以获取字符串似乎有点过于复杂...使用 StringWriter ,您可以直接获取字符串
【解决方案2】:

可以直接序列化成XmlDocument

XmlDocument doc = new XmlDocument();
XPathNavigator nav = doc.CreateNavigator();
using (XmlWriter w = nav.AppendChild())
{
    XmlSerializer ser = new XmlSerializer(typeof(MyType));
    ser.Serialize(w, myObject);
}

【讨论】:

  • 我认为 ser.Serializer 不接受对象作为参数?
  • 嗯,不错...而且不涉及中间字符串 :)
  • 如果我不够清楚,上面的代码无法编译,因为 ser.Serialize 有一些无效参数。否则它看起来像一个优雅的解决方案。
  • 但由于它不是一个合适的基准,它可能会给出一个错误的性能概念。
  • @randomuser:没有中间 Stream 或 TextReader 对象。如果您只需要这些对象来构造 XmlDocument,那么为什么要打扰它们呢?
【解决方案3】:

扩展@JohnSaunders 解决方案,我编写了以下通用函数:

public XmlDocument SerializeToXml<T>(T source) {
    var document = new XmlDocument();
    var navigator = document.CreateNavigator();

    using (var writer = navigator.AppendChild()) {
        var serializer = new XmlSerializer(typeof(T));
        serializer.Serialize(writer, source);
    }
    return document;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 2019-12-22
    • 1970-01-01
    相关资源
    最近更新 更多