获取给定PHP对象并将其序列化为XML的最佳方法是什么?我正在看simple_xml,我用它来将XML解析为对象,但我不清楚它是如何工作的.
我上周花了很长时间研究序列化.在那段时间里,我发现了很多使用BinaryFormatter或XmlSerializer的例子.不幸的是,我没有找到任何全面详细说明两者之间差异的例子.
我的好奇心的起源在于为什么BinaryFormatter能够直接反序列化到接口而XmlSerializer不能.Jon Skeet在回答" 在运行时转换为多个(未知类型) "时提供了直接二进制序列化到接口的示例.Stan R.在他对" XML Object Deserialization to Interface "的回答中使用XmlSerializer为我提供了实现目标的方法.
除了明显的BinaryFormatter利用二进制序列化,而XmlSerializer使用XML我想更全面地理解基本差异.何时使用其中一种或各自的利弊.
.net c# serialization xml-serialization binary-serialization
我想要XML格式如下:
<configuration><!-- Only one configuration node -->
<logging>...</logging><!-- Only one logging node -->
<credentials>...</credentials><!-- One or more credentials nodes -->
<credentials>...</credentials>
</configuration>
Run Code Online (Sandbox Code Playgroud)
我正在尝试创建一个Configuration
具有该[Serializable]
属性的类.要序列化凭据节点,我有以下内容:
[XmlArray("configuration")]
[XmlArrayItem("credentials", typeof(CredentialsSection))]
public List<CredentialsSection> Credentials { get; set; }
Run Code Online (Sandbox Code Playgroud)
但是,当我将其序列化为XML时,XML的格式如下:
<configuration>
<logging>...</logging>
<configuration><!-- Don't want credentials nodes nested in a second
configuration node -->
<credentials>...</credentials>
<credentials>...</credentials>
</configuration>
</configuration>
Run Code Online (Sandbox Code Playgroud)
如果我删除该[XmlArray("configuration")]
行,我会得到以下内容:
<configuration>
<logging>...</logging>
<Credentials><!-- Don't want credentials nodes nested in Credentials node -->
<credentials>...</credentials>
<credentials>...</credentials>
</Credentials>
</configuration>
Run Code Online (Sandbox Code Playgroud)
如何<credentials>
在单根节点中使用多个节点以我想要的方式对其进行序列化<configuration>
?我想这样做而不必实现 …
我目前正在开发一个项目,它需要持久保存任何类型的对象(我们没有任何控制权的实现),因此这些对象可以在之后恢复.
我们无法实现ORM,因为我们无法在开发时限制库的用户.
我们的第一个选择是使用Java默认序列化对其进行序列化,但是当用户开始传递同一对象的不同版本(属性更改类型,名称等)时,我们在恢复对象时遇到了很多麻烦.
我们尝试过使用XMLEncoder类(将对象转换为XML),但我们发现缺少功能(例如,不支持Enums).
最后,我们还尝试了JAXB,但这会强制我们的用户注释他们的类.
还有什么好办法吗
我无法相信我无法轻易获得这些信息,因此:
1)如果没有对它们进行实体编码,哪些字符不能合并到XML属性中?
显然,您需要编码引号.怎么样<
和>
?还有什么?
2)官方名单到底在哪里?
如何从使用DataContractSerializer序列化的对象的XML表示中删除XML命名空间?
该对象需要序列化为非常简单的输出XML.
宾语:
[Serializable]
class MyObj
{
string str;
Exception ex;
ISubObject subobj;
}
Run Code Online (Sandbox Code Playgroud)
需要序列化为:
<xml>
<str>...</str>
<ex i:nil="true" />
<subobj i:type="Abc">
<AbcProp1>...</AbcProp1>
<AbcProp2>...</AbcProp2>
</subobj>
</xml>
Run Code Online (Sandbox Code Playgroud)
我用过这段代码:
private static string ObjectToXmlString(object obj)
{
if (obj == null) throw new ArgumentNullException("obj");
var serializer =
new DataContractSerializer(
obj.GetType(), null, Int32.MaxValue, false, false, null,
new AllowAllContractResolver());
var sb = new StringBuilder();
using (var xw = XmlWriter.Create(sb, new XmlWriterSettings
{
OmitXmlDeclaration = true,
NamespaceHandling …
Run Code Online (Sandbox Code Playgroud) 我将简化代码以节省空间,但所呈现的内容确实说明了核心问题.
我有一个类,它有一个基类型的属性.有3个派生类可以分配给该属性.
如果我将任何派生类分配给容器并尝试序列化容器,则XmlSerializer会抛出可怕的:
"不期望类型x.使用XmlInclude或SoapInclude属性指定静态未知的类型."
但是我的基类已经用该属性修饰,所以我认为必须有一个额外的"隐藏"要求.
真正奇怪的是,默认的WCF序列化程序对此类层次结构没有任何问题.
Container类
[DataContract]
[XmlRoot(ElementName = "TRANSACTION", Namespace = Constants.Namespace)]
public class PaymentSummaryRequest : CommandRequest
{
[DataMember]
public PaymentSummary Summary { get; set; }
public PaymentSummaryRequest()
{
Mechanism = CommandMechanism.PaymentSummary;
}
}
Run Code Online (Sandbox Code Playgroud)
基类
[DataContract]
[XmlInclude(typeof(xPaymentSummary))]
[XmlInclude(typeof(yPaymentSummary))]
[XmlInclude(typeof(zPaymentSummary))]
[KnownType(typeof(xPaymentSummary))]
[KnownType(typeof(yPaymentSummary))]
[KnownType(typeof(zPaymentSummary))]
public abstract class PaymentSummary
{
}
Run Code Online (Sandbox Code Playgroud)
派生类之一
[DataContract]
public class xPaymentSummary : PaymentSummary
{
}
Run Code Online (Sandbox Code Playgroud)
序列化代码
var serializer = new XmlSerializer(typeof(PaymentSummaryRequest));
serializer.Serialize(Console.Out,new PaymentSummaryRequest{Summary = new xPaymentSummary{}});
Run Code Online (Sandbox Code Playgroud)
例外
System.InvalidOperationException:生成XML文档时出错.---> System.InvalidOperationException:不期望类型为xPaymentSummary.使用XmlInclude或SoapInclude属性指定静态未知的类型.在
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPaymentSummaryRequest.Write13_PaymentSummary(String n,String ns,PaymentSummary o,Boolean isNullable,Boolean needType)at at …
我是否可以在反序列化时使XmlSerializer忽略名称空间(xmlns属性),以便无论是否添加属性,或者即使属性是伪造的也无关紧要?我知道源始终是可信的,所以我不关心xmlns属性.
假设我有一个只有一个成员字符串的简单类.
public class Abc
{
private String text;
public String Text
{
get { return this.text; }
set { this.text = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
现在,当我使用可疑的XmlSerializer对其进行序列化然后反序列化时,任何包含换行符('\ r \n'或Environment.NewLine)的文本都将转换为'\n'.
我如何保留换行符?
我有一个关于datacontractserializer的快速问题.也许这更像是一个流问题.我发现了一段将xml写入文件流的代码.我基本上不想要文件,只需要字符串输出.
public static string DataContractSerializeObject<T>(T objectToSerialize)
{
var fs = new FileStream("test.xml", FileMode.OpenOrCreate);
var serializer = new DataContractSerializer(typeof(T));
serializer.WriteObject(fs, objectToSerialize);
fs.Close();
return fs.ToString();
}
Run Code Online (Sandbox Code Playgroud)
fs.ToString()显然不是我想要的.什么流或编写器等,我可以只使用返回正确的字符串而不创建文件?我确实查看了文件流创建的XML,这正是我正在寻找的.XmlSerializer编写的XML有点奇怪,在这种情况下我更喜欢DataContractSerializer的输出.谁能指出我正确的方向?