gpt4 book ai didi

java - XML 序列化引用 - 重复

转载 作者:数据小太阳 更新时间:2023-10-29 02:29:52 32 4
gpt4 key购买 nike

[Java 或 C#] 我在序列化方面遇到了一些问题。如何不复制有关对象的所有信息并仅使用引用?

示例类:

class Author {
public String id;
public String name;
}

class Book {
public String id;
public Author author;
public String title;
}

我必须像这里一样格式化输出文件:

<store>
<authors>
<author id="PK">
<name>Philip Kindred</name>
</author>
</authors>

<books>
<book id="u1">
<author>PK</author> <!-- use only ID -->
<title>Ubik</title>
</book>
</books>
</store>

最佳答案

您面临的问题是在 XML 中表示聚合关系而不是组合关系。当您在父子关系中保持父子关系(即组合)时,XML 序列化非常简单。在这种情况下,一本书有一位(或多位)作者,但并不拥有这本书,因为一位作者可以是许多其他书籍的作者。

在那种情况下,你可以做一些类似于数据库中的事情,即有两个单独的条目并通过外键表达关系。请参见下面的示例:

[Serializable]
public class Author
{
[XmlAttribute("id")]
public String Id { get; set; }
[XmlElement("name")]
public String Name { get; set; }
}

[Serializable]
public class Book
{
private Author _author;

[XmlIgnore]
public Author Author
{
get { return _author; }
set
{
_author = value;
AuthorId = _author != null ? _author.Id : null;
}
}

[XmlAttribute("id")]
public String Id { get; set; }

[XmlElement("author")]
public String AuthorId { get; set; }

[XmlElement("title")]
public String Title { get; set; }
}

[Serializable]
public class Store
{
[XmlArray("authors")]
[XmlArrayItem("author", Type = typeof(Author))]
public List<Author> Authors { get; set; }

[XmlArray("books")]
[XmlArrayItem("book", Type = typeof(Book))]
public List<Book> Books { get; set; }

public Store()
{
Books = new List<Book>();
Authors = new List<Author>();
}
}


internal class Program
{
private static void Main(string[] args)
{
// Create some authors
var authors = new List<Author>
{
new Author{Id="PK", Name="Philip Kindred"},
new Author{Id="WS", Name="William Shakespeare"},
};

// Create some books linked to the authors
var books = new List<Book>
{
new Book{Id = "U1", Author = authors[0], Title = "Do Androids Dream of Electric Sheep?"},
new Book{Id = "U2", Author = authors[1], Title = "Romeo and Juliet"}
};

var store = new Store {Authors = authors, Books = books};

var success = Serialiser.SerialiseToXml(store, "store.xml");

// Deserialize the data from XML
var store2 = Serialiser.DeserialseFromXml<Store>("store.xml");

// Resolve the actual Author instances from the saved IDs (foreign key equivalent in databases)
foreach (var book in store2.Books)
book.Author = store2.Authors.FirstOrDefault(author => author.Id == book.AuthorId);

// Now variable 'store' and 'store2' have the same equivalent data
}
}

// Helper class to serialize and deserialize the data to XML file
public static class Serialiser
{
public static bool SerialiseToXml(object obj, string filename)
{
try
{
var ws = new XmlWriterSettings
{
NewLineHandling = NewLineHandling.Entitize,
NewLineChars = Environment.NewLine,
Indent = true,
NewLineOnAttributes = false
};
var xs = new XmlSerializer(obj.GetType());
using (var writer = XmlWriter.Create(filename, ws))
xs.Serialize(writer, obj);

return true;
}
catch(Exception ex)
{
return false;
}
}

public static T DeserialseFromXml<T>(string filename) where T : new()
{
var typeofT = typeof(T);
try
{
var xs = new XmlSerializer(typeofT);
using (var reader = XmlReader.Create(filename))
return (T)xs.Deserialize(reader);
}
catch(Exception ex)
{
return default(T);
}
}
}

“store.xml”将如下所示:

<?xml version="1.0" encoding="utf-8"?>
<Store xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<authors>
<author id="PK">
<name>Philip Kindred</name>
</author>
<author id="WS">
<name>William Shakespeare</name>
</author>
</authors>
<books>
<book id="U1">
<author>PK</author>
<title>Do Androids Dream of Electric Sheep?</title>
</book>
<book id="U2">
<author>WS</author>
<title>Romeo and Juliet</title>
</book>
</books>
</Store>

关于java - XML 序列化引用 - 重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27672434/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com