首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XmlSerializer将C#对象转换为xml字符串

XmlSerializer将C#对象转换为xml字符串
EN

Stack Overflow用户
提问于 2013-07-19 06:20:55
回答 4查看 77.8K关注 0票数 8

我创建了一个C#类:

代码语言:javascript
复制
public class books {
    public int bookNum { get; set; }
    public class book {
        public string name { get; set; }
        public class record {
            public string borrowDate { get; set; }
            public string returnDate { get; set; }
        }
        public record[] records { get; set; }
    }
    public book[] books { get; set; }
}

而是当我使用XmlSerializer转换为XML时。结果与下面的xml不一样。

我的C#课有什么问题?我希望使用XmlSerializer来输出结果,而不是使用XmlDocument。

有什么想法吗?提前感谢!

代码语言:javascript
复制
<books>
    <bookNum>2</bookNum>
    <book>
        <name>Book 1</name>
        <record>
            <borrowDate>2013-7-1</borrowDate>
            <returnDate>2013-7-12</returnDate>
        </record>
        <record>            
            <borrowDate>2013-8-1</borrowDate>
            <returnDate>2013-8-5</returnDate>
        </record>
    </book>
    <book>
        <name>Book 2</name>
        <record>
            <borrowDate>2013-6-1</borrowDate>
            <returnDate>2013-6-12</returnDate>
        </record>
        <record>            
            <borrowDate>2013-7-1</borrowDate>
            <returnDate>2013-7-5</returnDate>
        </record>
    </book>
</books>

编辑

下面是我的C#代码和输出结果:

代码语言:javascript
复制
books books = new books {
        bookNum = 2,
        Books = new books.book[] { 
            new books.book {  
                name = "Book1", 
                records = new books.book.record[] {
                    new books.book.record {
                        borrowDate = "2013-1-3",
                        returnDate = "2013-1-5"
                    },
                     new books.book.record {
                        borrowDate = "2013-2-3",
                        returnDate = "2013-4-5"
                    }
                }
            },
             new books.book {  
                name = "Book1", 
                records = new books.book.record[] {
                    new books.book.record {
                        borrowDate = "2013-1-3",
                        returnDate = "2013-1-5"
                    },
                     new books.book.record {
                        borrowDate = "2013-2-3",
                        returnDate = "2013-4-5"
                    }
                }
            }
        }
    };


    XmlSerializer xsSubmit = new XmlSerializer(typeof(books));

    XmlDocument doc = new XmlDocument();

    System.IO.StringWriter sww = new System.IO.StringWriter();
    XmlWriter writer = XmlWriter.Create(sww);
    xsSubmit.Serialize(writer, books);
    var xml = sww.ToString(); // Your xml
    context.Response.Write(xml);

XML:

代码语言:javascript
复制
<books>
    <bookNum>2</bookNum>
    <Books>
        <book>
            <name>Book1</name>
            <records>
                <record>
                    <borrowDate>2013-1-3</borrowDate>
                    <returnDate>2013-1-5</returnDate>
                </record>
                <record>
                    <borrowDate>2013-2-3</borrowDate>
                    <returnDate>2013-4-5</returnDate>
                </record>
            </records>
        </book>
        <book>
            <name>Book1</name>
            <records>
                <record>
                    <borrowDate>2013-1-3</borrowDate>
                    <returnDate>2013-1-5</returnDate>
                </record>
                <record>
                    <borrowDate>2013-2-3</borrowDate>
                    <returnDate>2013-4-5</returnDate>
                </record>
            </records>
         </book>
    </Books>
</books>
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-07-19 06:30:18

您不能使用标准序列化工具从您的问题中序列化类,以便它将具有与<bookNum>节点相同的级别上的<bookNum>条目。

当用标准序列化工具保存类时,<book>节点的列表总是嵌套在与<bookNum>节点相同级别的单独数组节点中。records数组字段在book类上也是如此。

要生成您想要的XML输出--将<book>节点放在与<bookNum>节点相同的级别--您必须在您的books类中实现IXmlSerializable接口,以便进行自定义序列化。要查看IXmlSerializable实现的示例,请访问以下链接:StackOverflow答案CodeProject文章

另一种解决方案是--正如我对我的答案的注释中所述的那样--从用户Alexandr类型继承books类,并在book类字段中拥有从List<record>类型继承的类类型的records

当从您的问题序列化类时,假设您分配的适当XmlRoot、XmlElement、XmlArray和XmlArrayItem属性如下:

代码语言:javascript
复制
[XmlRoot("books")]
public class books
{
    [XmlElement("bookNum")]
    public int bookNum { get; set; }

    [XmlRoot("book")]
    public class book
    {
        [XmlElement("name")]
        public string name { get; set; }

        [XmlRoot("record")]
        public class record
        {
            [XmlElement("borrowDate")]
            public string borrowDate { get; set; }

            [XmlElement("returnDate")]
            public string returnDate { get; set; }
        }

        [XmlArray("borrowRecords")]
        [XmlArrayItem("record")]
        public record[] records { get; set; }
    }

    [XmlArray("booksList")]
    [XmlArrayItem("book")]
    public book[] books { get; set; }
}

您将得到如下XML输出:

代码语言:javascript
复制
<books>
    <bookNum>2</bookNum>
    <booksList>
        <book>
            <name>Book 1</name>
            <borrowRecords>
                <record>
                    <borrowDate>2013-1-3</borrowDate>
                    <returnDate>2013-1-5</returnDate>
                </record>
                <record>            
                    <borrowDate>2013-2-3</borrowDate>
                    <returnDate>2013-4-5</returnDate>
                </record>
            </borrowRecords>
        </book>
        <book>
            <name>Book 2</name>
            <borrowRecords>
                <record>
                    <borrowDate>2013-1-3</borrowDate>
                    <returnDate>2013-1-5</returnDate>
                </record>
                <record>            
                    <borrowDate>2013-2-3</borrowDate>
                    <returnDate>2013-4-5</returnDate>
                </record>
            </borrowRecords>
        </book>
    </booksList>
</books>
票数 9
EN

Stack Overflow用户

发布于 2013-07-19 06:46:11

我对您的类代码做了以下更改。我无法使用默认序列化程序复制XML序列化,因为如果不给它一个容器元素,它就不会复制“Record”元素。

代码语言:javascript
复制
[System.Xml.Serialization.XmlRoot("books")]
public class books 
{
    public int bookNum { get; set; }
    public class book {
        public string name { get; set; }
        public class record {
            public string borrowDate { get; set; }
            public string returnDate { get; set; }
        }
        public record[] records { get; set; }
    }
    public book[] books { get; set; }
}

序列化这将给我以下输出

代码语言:javascript
复制
<books xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <bookNum>2</bookNum>
  <books>
    <book>
      <name>first</name>
      <records>
        <record>
          <borrowDate>19/07/2013 4:41:29 PM</borrowDate>
          <returnDate>19/07/2013 4:41:29 PM</returnDate>
        </record>
      </records>
    </book>
  </books>
</books>

使用此测试代码

代码语言:javascript
复制
books bks = new books();
bks.bookNum = 2;
bks.books = new books.book[]{ new books.book{name="first", records = new books.book.record[] {new books.book.record{borrowDate = DateTime.Now.ToString(), returnDate = DateTime.Now.ToString()}}}};

System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(books));

XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = new UnicodeEncoding(false, false); // no BOM in a .NET string
settings.Indent = true;
settings.OmitXmlDeclaration = true;

using(StringWriter textWriter = new StringWriter()) {
    using(XmlWriter xmlWriter = XmlWriter.Create(textWriter, settings)) {
        serializer.Serialize(xmlWriter, bks);
    }
    return textWriter.ToString(); //This is the output as a string
}
票数 8
EN

Stack Overflow用户

发布于 2016-02-03 00:59:49

我意识到这已经晚了几年,但是我已经能够通过使用XmlElementAttribute来实现您想要的结构。

我通过使用XSD.exe从xml生成模式定义和从xsd文件生成.Net代码来发现这一点。据我所知,这在.Net 3.5到4.6中是可行的。

下面是我使用的类定义:

代码语言:javascript
复制
public class books
{
    public int bookNum { get; set; }
    public class book {
        public string name { get; set; }
        public class record {
            public string borrowDate { get; set; }
            public string returnDate { get; set; }
        }
        [XmlElement("record")]
        public record[] records { get; set; }
    }
    [XmlElement("book")]
    public book[] allBooks { get; set; }
}

下面是一个LinqPad片段,它演示了序列化/反序列化(基于David的代码片段,感谢BTW关于如何排除BOM的技巧,这正是我正在寻找的):

代码语言:javascript
复制
books bks = new books();
books bks2 = null;
bks.bookNum = 2;
bks.allBooks = new books.book[] 
        { 
            new books.book {
                name="book 1", 
                records = new books.book.record[] {
                        new books.book.record{borrowDate = DateTime.Now.ToString(), returnDate = DateTime.Now.ToString()}
                    }
                },
            new books.book { 
                name="book 2", 
                records = new books.book.record[] { 
                        new books.book.record{borrowDate = DateTime.Now.ToString(), returnDate = DateTime.Now.ToString()}, 
                        new books.book.record{borrowDate = DateTime.Now.ToString(), returnDate = DateTime.Now.ToString()}}
                    },
        };
string xmlString;

System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(books));

XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = new UnicodeEncoding(false, false); // no BOM in a .NET string
settings.Indent = true;
settings.OmitXmlDeclaration = true;

XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
// exclude xsi and xsd namespaces by adding the following:
ns.Add(string.Empty, string.Empty);

using(StringWriter textWriter = new StringWriter()) {
    using(XmlWriter xmlWriter = XmlWriter.Create(textWriter, settings)) {
        serializer.Serialize(xmlWriter, bks, ns);
    }
    xmlString = textWriter.ToString(); //This is the output as a string
}

xmlString.Dump();

// Deserialize the xml string now       
using ( TextReader reader = new StringReader(xmlString) ) {
    bks2 = ( books )serializer.Deserialize(reader);
}

bks2.Dump();

这个生成的XML可以在不实现IXmlSerializable的情况下被序列化和反序列化,例如:

代码语言:javascript
复制
<books>
  <bookNum>2</bookNum>
  <book>
    <name>book 1</name>
    <record>
      <borrowDate>2/2/2016 5:57:25 PM</borrowDate>
      <returnDate>2/2/2016 5:57:25 PM</returnDate>
    </record>
  </book>
  <book>
    <name>book 2</name>
    <record>
      <borrowDate>2/2/2016 5:57:25 PM</borrowDate>
      <returnDate>2/2/2016 5:57:25 PM</returnDate>
    </record>
    <record>
      <borrowDate>2/2/2016 5:57:25 PM</borrowDate>
      <returnDate>2/2/2016 5:57:25 PM</returnDate>
    </record>
  </book>
</books>
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17739330

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档