在C#中,我有一个类,它有一个派生属性,应该通过XML序列化.但是,XML序列化(默认情况下)不会序列化read = only属性.我可以通过定义一个空的setter来解决这个问题:
public virtual string IdString
{
get { return Id.ToString("000000"); }
set { /* required for xml serialization */ }
}
Run Code Online (Sandbox Code Playgroud)
但是,除了编写自己的ISerializable实现之外,还有一种更清晰,语义更正确的方法吗?
我正在序列化这样的类
public MyClass
{
public int? a { get; set; }
public int? b { get; set; }
public int? c { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
所有类型都可以为空,因为我希望在序列化此类对象时存储最少的数据.但是,当它仅使用"a"进行序列化时,我得到以下xml
<MyClass ...>
<a>3</a>
<b xsi:nil="true" />
<c xsi:nil="true" />
</MyClass>
Run Code Online (Sandbox Code Playgroud)
如何将此设置为仅获取非null属性的xml?期望的输出将是
<MyClass ...>
<a>3</a>
</MyClass>
Run Code Online (Sandbox Code Playgroud)
我想排除这些空值,因为会有几个属性,这是存储在数据库中(是的,这不是我的调用)所以我想保持未使用的数据最小.
我是使用.NET进行XML序列化的新手,在使用它一段时间之后我现在非常费力.我可以使用包含其他元素的属性来序列化元素,但是如何序列化类似的元素
<myElement name="foo">bar</myElement>
Run Code Online (Sandbox Code Playgroud)
我为myElement使用了一个带有XmlAttribute的"name"类,但是如何引用XML Element的值?
提前致谢.
一旦设置了初始值,我就有几个不可变的类.Eric Lippert称之为一次性写入不可变性.
在C#中实现一次写入不变性通常意味着通过构造函数设置初始值.这些值初始化只读字段.
但是,如果需要使用XmlSerializer或DataContractSerializer将类似这样的类序列化为XML,则必须具有无参数构造函数.
有没有人建议如何解决这个问题?是否有其他形式的不变性可以更好地与序列化?
编辑:正如@Todd所指出的,DataContractSerializer不需要无参数构造函数.根据MSDN上的DataContractSerializer文档,DataContractSerializer"不会调用目标对象的构造函数."
我有一个类似于以下的XML文档:
<scan_details>
<object name="C:\Users\MyUser\Documents\Target1.doc">
...
</object>
<object name="C:\Users\MyUser\Documents\Target2.doc">
...
</object>
...
</scan_details>
Run Code Online (Sandbox Code Playgroud)
我希望使用这些System.Xml.Serialization
属性来简化XML反序列化.我遇到的问题是我无法弄清楚如何指定根节点包含一个数组.
我尝试过创建以下类:
[XmlRoot("scan_details")]
public class ScanDetails
{
[XmlArray("object")]
public ScanDetail[] Items { get; set; }
}
public class ScanDetail
{
[XmlAttribute("name")]
public string Filename { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
但是,当我将XML反序列化为ScanDetails
对象时,Items
数组仍然存在null
.
如何反序列化根节点中的数组?
我正在使用Microsoft Dynamics CRM进行一些实验.您通过Web服务与它进行交互,并且我已将Web引用添加到我的项目中.Web服务接口非常丰富,生成的"Reference.cs"大约是90k loc.
我在控制台应用程序中使用Web引用.我经常改变一些东西,重新编译并运行.编译速度很快,但是新建Web服务引用非常慢,花费大约15-20秒:
CrmService service = new CrmService();
分析显示所有时间都花在SoapHttpClientProtocol构造函数中.
罪魁祸首显然是XML序列化代码(不包括在上面提到的90k loc中)是在运行时生成,然后才进行JIT.这在构造函数调用期间发生.在玩耍和尝试时,等待是相当令人沮丧的.
我尝试了sgen.exe,ngen和XGenPlus的各种组合(需要几个小时并生成500MB的额外代码),但无济于事.我已经考虑过实现一个几乎没有CrmService实例的Windows服务,可以在需要的时候发布,但这似乎太过分了.
有任何想法吗?
.net c# performance xml-serialization soaphttpclientprotocol
在序列化对象时,如何向XmlArray元素(而不是XmlArrayItem)添加属性?
对不起,我是一个Java/XML新手 - 似乎无法想象这一个.似乎可以将Document对象转换为字符串.但是,我想将Node对象转换为字符串.我正在使用org.ccil.cowan.tagsoup Parser.
我正在通过类似的方式检索节点...
parser = new org.ccil.cowan.tagsoup.Parser()
parser.setFeature(namespaceaware, false)
Transformer transformer = TransformerFactory.newInstance().newTransformer();
DOMResult domResult = new DOMResult();
transformer.transform(new SAXSource(parser, new InputSource(in)), domResult);
Node n = domResult.getNode();
// I'm interested in the first child, so...
Node myNode = n.getChildNodes().item(0);
// convert myNode to string..
// what to do here?
Run Code Online (Sandbox Code Playgroud)
答案可能很明显,但我似乎无法从核心Java库中弄清楚如何实现这一目标.任何帮助深表感谢!
我有一个键/值对列表,我想存储和从XML文件中检索.所以此任务与此处描述的类似.我试图遵循标记答案中的建议(使用KeyValuePair和XmlSerializer),但我没有得到它的工作.
到目前为止,我所拥有的是"设置"课程......
public class Settings
{
public int simpleValue;
public List<KeyValuePair<string, int>> list;
}
Run Code Online (Sandbox Code Playgroud)
......这个班的一个例子......
Settings aSettings = new Settings();
aSettings.simpleValue = 2;
aSettings.list = new List<KeyValuePair<string, int>>();
aSettings.list.Add(new KeyValuePair<string, int>("m1", 1));
aSettings.list.Add(new KeyValuePair<string, int>("m2", 2));
Run Code Online (Sandbox Code Playgroud)
...以及将该实例写入XML文件的以下代码:
XmlSerializer serializer = new XmlSerializer(typeof(Settings));
TextWriter writer = new StreamWriter("c:\\testfile.xml");
serializer.Serialize(writer, aSettings);
writer.Close();
Run Code Online (Sandbox Code Playgroud)
生成的文件是:
<?xml version="1.0" encoding="utf-8"?>
<Settings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<simpleValue>2</simpleValue>
<list>
<KeyValuePairOfStringInt32 />
<KeyValuePairOfStringInt32 />
</list>
</Settings>
Run Code Online (Sandbox Code Playgroud)
因此,虽然元素的数量是正确的,但是我的列表中的对的键和值都没有存储.显然我做的事情基本上是错的.我的问题是:
让我们假设我有这个对象:
[Serializable]
public class MyClass
{
public int Age { get; set; }
public int MyClassB { get; set; }
}
[Serializable]
public class MyClassB
{
public int RandomNumber { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
XmlSerializer会像这样序列化对象:
<MyClass>
<Age>0</age>
<MyClassB>
<RandomNumber>4234</RandomNumber>
</MyClassB>
</MyClass>
Run Code Online (Sandbox Code Playgroud)
我怎样才能使该物业成为可空?IE:当它低于0时,没有序列化属性Age?
我尝试使用Nullable,但它将我的对象序列化为:
<MyClass>
<Age d5p1:nil="true" />
<MyClassB>
<RandomNumber>4234</RandomNumber>
</MyClassB>
</MyClass>
Run Code Online (Sandbox Code Playgroud)
通过阅读MSDN文档,我发现了这个:
您不能将IsNullable属性应用于键入为值类型的成员,因为值类型不能包含nullNothingnullptra null引用(在Visual Basic中为Nothing).此外,对于可空值类型,您不能将此属性设置为false.当这些类型为nullNothingnullptra null引用(在Visual Basic中为Nothing)时,它们将通过将xsi:nil设置为true来序列化.
来源:http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlelementattribute.isnullable.aspx
我理解值类型不能设置为null.值类型始终设置为某个值.序列化不能根据它的当前值决定是否序列化它.
我尝试了属性,但它没有成功.我尝试创建一个agecontainer对象并使用属性操作它的序列化,但它没有成功.
我真正想要的是:
<MyClass>
<MyClassB>
<RandomNumber>4234</RandomNumber>
</MyClassB>
</MyClass>
Run Code Online (Sandbox Code Playgroud)
当属性Age低于0(零)时.
看起来你必须实现自定义序列化.
是的,那也是我的意思,但我想在没有它的情况下逃脱.
在应用程序中,对象要复杂得多,我不想自己处理序列化.
c# ×8
.net ×4
arrays ×1
immutability ×1
java ×1
list ×1
null ×1
nullable ×1
performance ×1
value-type ×1
xml ×1