代码之家  ›  专栏  ›  技术社区  ›  Christopher

如何控制<?XML?>使用.NET进行XML序列化的一部分?

  •  13
  • Christopher  · 技术社区  · 15 年前

    我正在使用此方法序列化我的对象:

    public static string XmlSerialize(object o)
    {
        var stringWriter = new StringWriter();
        var xmlSerializer = new XmlSerializer(o.GetType());
        xmlSerializer.Serialize(stringWriter, o);
        string xml = stringWriter.ToString();
        stringWriter.Close();
        return xml;
    }
    

    它使XML以如下方式开始:

    <?xml version="1.0" encoding="utf-16"?>
    <MyObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    

    但我希望它看起来像这样:

    <?xml version = "1.0" encoding="Windows-1252" standalone="yes"?>
    <MyObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    

    那么,如何将编码更改为Windows-1252并将standalone设置为yes? 另外,如何让对象排除xmlns值?

    我也看到过一些类似的问题,比如 this one 但我希望这对我来说可能更简单,也许通过在某个地方设置一些属性?

    更新2:在看了约翰的回答和评论之后,再考虑这个问题,我决定做第二种方法。我不认为仅仅为第三方创建这种奇怪的定制XML,一开始就应该被称为“xmlserialize”这样的通用XML。

    因此,我创建了第二个方法,它采用XML文档,首先,删除一个这样的命名空间元素:

    xElement.Attributes().Where(a => a.IsNamespaceDeclaration && a.Value == "http://www.w3.org/2001/XMLSchema").Remove();
    

    然后,它用john的代码将其写入XML。最后,它返回该XML,并遵循以下输出:

    new XDeclaration("1.0", "Windows-1252", "yes").ToString()
    

    这很难看,但这正是我需要的第三方来理解我的XML。

    3 回复  |  直到 10 年前
        1
  •  25
  •   John Saunders    11 年前

    试试这个:

    public static string XmlSerialize(object o)
    {
        using (var stringWriter = new StringWriter())
        {
            var settings = new XmlWriterSettings
                               {
                                   Encoding = Encoding.GetEncoding(1252),
                                   OmitXmlDeclaration = true
                               };
            using (var writer = XmlWriter.Create(stringWriter, settings))
            {
                var xmlSerializer = new XmlSerializer(o.GetType());
                xmlSerializer.Serialize(writer, o);
            }
            return stringWriter.ToString();
        }
    }
    

    这不会消除xsd:namespace,但是,为什么要这样做?


    更新: 似乎每当你使用 StringWriter ,即使使用 XmlWriter 上面有编码集。下一步将是写出 MemoryStream .但这就提出了一个问题,为什么要返回一个字符串。例如,如果您只需要返回并将字符串输出到流,那么我们应该直接输出到该流。同样适用于 TextWriter .

        2
  •  2
  •   Ryall    15 年前

    您可以使用 XmlTextWriter 而不是编剧。下面是从我的代码中提取的您的编码集。

    XmlTextWriter textWriter = new XmlTextWriter(stream, Encoding.GetEncoding(1252));
    textWriter.Namespaces = false;
    
        3
  •  0
  •   GTAE86    10 年前

    fwiw,我通过使用带有xmlWritersettings的xmlWriter来实现编码。这是一个示例:

    ...  
    // My object type was from a class generated by xsd.  
    XmlSerializer xms = new XmlSerializer(typeof(SomeType));  
    SomeType objSt;
    using(FileStream fs = new FileStream("C:\SomeFile.xml", FileMode.Open, FileAccess.Read))
    {    
      using(XmlReader xr = XmlReader.Create(fs))  // Supposed to preserve encoding.  
      {  
        objSt = (SomeType)xms.Deserialize(xr);  
      }    
    }  
    
    ...  
    ...  // Do some stuff, change some attribute values.  
    ...  
    
    XmlWriterSettings xsw= new XmlWriterSettings();  
    xsw.Indent= true;  
    xsw.NewLineOnAttributes= true;  
    xsw.Encoding = Encoding.GetEncoding(1252);  
    using(XmlWriter xwXsw = XmlWriter.Create("C:\SomeFile_Changed.xml",xsw))
    {    
      xms.Serialize(xwXsw, objSt);  
    }  
    ...  
    ...  // Finish up and get out.
    ...  
    

    出于某种原因,我只需要使用XmlSerializer对象并使用一个文本编写器序列化,就可以让它全部工作一次,因为根据XmlSerializer的MS帮助,“反序列化(XmlReader)”XmlReader自动检测并使用XML文档指定的编码。“然后我开始使用XmlWriterSettings并中断一些事情。。。。