我一直在谷歌搜索过去几个小时并尝试不同的东西,但似乎不能在这个底部....
当我运行此代码时,内存使用量不断增长.
while (true)
{
try
{
foreach (string sym in stringlist)
{
StreamReader r = new StreamReader(@"C:\Program Files\" + sym + ".xml");
XmlSerializer xml = new XmlSerializer(typeof(XMLObj), new XmlRootAttribute("rootNode"));
XMLObj obj = (XMLObj)xml.Deserialize(r);
obj.Dispose();
r.Dispose();
r.Close();
}
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString());
}
Thread.Sleep(1000);
Console.Clear();
}
Run Code Online (Sandbox Code Playgroud)
XMLObj是一个自定义对象
[Serializable()]
public class XMLObj: IDisposable
{
[XmlElement("block")]
public List<XMLnode> nodes{ get; set; }
public XMLObj() { }
public void Dispose()
{
nodes.ForEach(n => n.Dispose());
nodes= null;
GC.SuppressFinalize(this);
}
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试添加GC.Collect(); 但这似乎没有做任何事情.
希望对于那里的人(可能是一个骗子)来说这应该是一个简单的答案,但我似乎无法弄明白.
我需要输出一个如下所示的元素:
<Quantity foo="AB" bar="CD">37</Quantity>
Run Code Online (Sandbox Code Playgroud)
我知道如何得到这个:
<Quantity foo="AB" bar="CD">
<qty>37</qty>
</Quantity>
Run Code Online (Sandbox Code Playgroud)
包含Quantity类
public int qty;
[XmlAttribute]
public string foo;
[XmlAttribute]
public string bar;
Run Code Online (Sandbox Code Playgroud)
但当然,无论我插入数量的变量是什么变成它自己的子元素.
另一方面,如果我在父元素中将Quantity作为变量,那么我可以设置值并获取
<Quantity>37</Quantity>
Run Code Online (Sandbox Code Playgroud)
但后来我不知道如何获得属性.
如果没有一个简单的方法来使用XmlSerializer,我会非常惊讶,但我还不知道.有任何想法吗?
我有以下最小的JavaScript片段:
var xml = '<El a:title="T" a:href="H" xmlns:a="http://www.w3.org/1999/xlink" />';
var dom = new DOMParser().parseFromString(xml, 'text/xml');
xml = new XMLSerializer().serializeToString(dom);
Run Code Online (Sandbox Code Playgroud)
当我在大多数浏览器中执行代码时(只需将其粘贴到浏览器的JavaScript控制台中),解析后序列化的XML与原始XML相同.例如在Chrome 8上,我得到:
<El xmlns:a="http://www.w3.org/1999/xlink" a:title="T" a:href="H"/>
Run Code Online (Sandbox Code Playgroud)
但是在Chrome 22上,相同的代码片段将XML更改为:
<El xmlns:a="http://www.w3.org/1999/xlink" xlink:title="T" xlink:href="H"/>
Run Code Online (Sandbox Code Playgroud)
请注意,xlinktitle和href属性使用的名称空间前缀未在任何位置定义,因此XML现在无效.正如您可能想象的那样,这会导致尝试随后使用XML的代码出现各种问题.
这是XMLSerializer中的错误还是我错过了关于如何序列化DOM的一些错综复杂的内容?
还有没有人找到我可以放在代码中的解决方法,而不是使XML匹配明显的首选项xlink用作XLink命名空间的前缀?
我做了一些额外的测试,问题似乎是因为XMLSerializer识别XLink命名空间并坚持xlink为它输出前缀,而没有正确注册该前缀.
所以这个片段工作正常:
var xml = '<El a:title="T" a:href="H" xmlns:a="any-other-namespace-uri" />';
var dom = new DOMParser().parseFromString(xml, 'text/xml');
xml = new XMLSerializer().serializeToString(dom);
Run Code Online (Sandbox Code Playgroud)
所以在这里我将名称空间URL更改为不太知名的东西,输出现在有效:
<El xmlns:a="any-other-namespace-uri" a:title="T" a:href="H"/>
Run Code Online (Sandbox Code Playgroud)
以下片段也可以正常工作:
var xml = '<El a:title="T" a:href="H" xmlns:a="http://www.w3.org/2000/xlink" />';
var dom = new DOMParser().parseFromString(xml, …Run Code Online (Sandbox Code Playgroud) 我在一个有很多字段的类上调用一个简单的XmlSerializer.Deserizlize()时遇到了巨大的性能损失.
注意:我在家里没有Visual Studio编写代码,因此可能会有一些错误.
我的可序列化类是扁平的,有数百个字段:
[Serializable]
class Foo
{
public Foo() { }
[XmlElement(ElementName = "Field1")]
public string Field1;
// [...] 500 Fields defined in the same way
[XmlElement(ElementName = "Field500")]
public string Field500;
}
Run Code Online (Sandbox Code Playgroud)
我的应用程序反序列化输入字符串(甚至很小):
StringReader sr = new StringReader(@"<Foo><Field1>foo</Field1></Foo>");
XmlSerializer serializer = new XmlSerializer(typeof(Foo));
object o = serializer.Deserialize(sr);
Run Code Online (Sandbox Code Playgroud)
运行在32位系统中的应用(或32位被迫corflags.exe),代码需要大约一秒钟的第一次(临时序列化类的生成,和所有的...),那么它的接近0.
在64位系统中运行应用程序,代码第一次占用一分钟,然后接近0.
在第一次执行XmlSerializer期间,对于大型类,在64位系统中,可能会将系统挂起这么长时间?
现在我不确定是否必须责怪临时类生成/删除,xml名称表初始化,CAS,Windows搜索,AntiVirus或圣诞老人......
破坏者
以下是我的测试,如果您不想被我(可能的)analysys错误所牵制,请不要阅读此内容.
为了进一步解释最后一点,如果我有一个班级:
[Serializable]
class Bar
{ …Run Code Online (Sandbox Code Playgroud) 我已经能够以这种方式序列化IEnumerable:
[XmlArray("TRANSACTIONS")]
[XmlArrayItem("TRANSACTION", typeof(Record))]
public IEnumerable<BudgetRecord> Records
{
get
{
foreach(Record br in _budget)
{
yield return br;
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我意识到现在我需要一个包含集合的字典Dictionary<string, RecordCollection>(RecordCollection实现IEnumerable).
我怎样才能做到这一点?
我有一个对象Foo,我将其序列化为XML流.
public class Foo {
// The application version, NOT the file version!
public string Version {get;set;}
public string Name {get;set;}
}
Foo foo = new Foo { Version = "1.0", Name = "Bar" };
XmlSerializer xmlSerializer = new XmlSerializer(foo.GetType());
Run Code Online (Sandbox Code Playgroud)
这可以快速,轻松地完成当前所需的一切.
我遇到的问题是我需要维护一个单独的文档文件,其中包含一些小的评论.如上例所示,Name很明显,但是Version应用程序版本而不是数据文件版本,正如人们在这种情况下所期望的那样.而且我还有许多类似的小事我想用评论来澄清.
我知道如果我使用该WriteComment()函数手动创建我的XML文件,我可以这样做,但是我可以实现可能的属性或替代语法,以便我可以继续使用序列化程序功能吗?
我知道ShouldSerialize*模式和*Specified模式以及它们是如何工作的,但两者之间有什么区别吗?
当某些事情应该有条件地序列化时,是否有任何"陷阱"使用一种方法而不是另一种方法?
此问题仅供使用XmlSerializer,但也欢迎有关此主题的一般信息.
关于这个主题的信息非常少,因此可能是因为它们执行完全相同的目的而且它是一种风格选择.然而,看起来奇怪的是.NET实现者会通过反射来分析类,并查找其中一个/两个模式来确定生成的序列化程序的行为,因为它会减慢序列化程序的生成速度,除非它只是一个向后兼容性工件.
编辑: 对于那些不熟悉这两个模式的人,如果*Specified属性或ShouldSerialize*方法返回true,则该属性被序列化.
public string MyProperty { get; set; }
//*Specified Pattern
[XmlIgnore]
public bool MyPropertySpecified { get{ return !string.IsNullOrWhiteSpace(this.MyProperty); } }
//ShouldSerialize* Pattern
public bool ShouldSerializeMyProperty()
{
return !string.IsNullOrWhiteSpace(this.MyProperty);
}
Run Code Online (Sandbox Code Playgroud) 我已经尝试了所有可以在SO和其他地方找到的解决方案,但似乎无法弄清楚为什么这不起作用.
将XML字符串直接反序列化为对象,该对象具有一个属性 - 一个List:
[XmlTypeAttribute(AnonymousType = true)]
public class UpdateData
{
[XmlArrayItem(ElementName = "Updates")]
public List<Update> Updates { get; set; }
public UpdateData()
{
Updates = new List<Update>();
}
}
public class Update
{
[XmlElement(ElementName = "MemberID")]
public int MemberID { get; set; }
[XmlElement(ElementName = "AnalysisID")]
public int AnalysisID { get; set; }
[XmlElement(ElementName = "MemberName")]
public string MemberName { get; set; }
[XmlElement(ElementName = "RecordDate")]
public DateTime RecordDate { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这是反序列化代码:
private object DeserialzeXml(string xml) …Run Code Online (Sandbox Code Playgroud) 我正在尝试生成一个XML文档,其中包含没有前缀的默认命名空间XmlSerializer,例如
<?xml version="1.0" encoding="utf-8" ?>
<MyRecord ID="9266" xmlns="http://www.website.com/MyRecord">
<List>
<SpecificItem>
Run Code Online (Sandbox Code Playgroud)
使用以下代码......
string xmlizedString = null;
MemoryStream memoryStream = new MemoryStream();
XmlSerializer xs = new XmlSerializer(typeof(ExportMyRecord));
XmlSerializerNamespaces xmlnsEmpty = new XmlSerializerNamespaces();
xmlnsEmpty.Add(string.Empty, string.Empty);
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
xs.Serialize(xmlTextWriter, myRecord, xmlnsEmpty);
memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
xmlizedString = this.UTF8ByteArrayToString(memoryStream.ToArray());
Run Code Online (Sandbox Code Playgroud)
和班级结构......
[Serializable]
[XmlRoot("MyRecord")]
public class ExportMyRecord
{
[XmlAttribute("ID")]
public int ID { get; set; }
Run Code Online (Sandbox Code Playgroud)
现在,我尝试了各种选择......
XmlSerializer xs = new XmlSerializer
(typeof(ExportMyRecord),"http://www.website.com/MyRecord");
Run Code Online (Sandbox Code Playgroud)
要么 ...
[XmlRoot(Namespace = "http://www.website.com/MyRecord", ElementName="MyRecord")]
Run Code Online (Sandbox Code Playgroud)
给我 ...
<?xml …Run Code Online (Sandbox Code Playgroud) 我想使用XmlSerializer生成以下内容:
<atom:link href="http://dallas.example.com/rss.xml" rel="self" type="application/rss+xml" />
Run Code Online (Sandbox Code Playgroud)
所以我尝试在我的元素中添加一个命名空间:
[...]
[XmlElement("link", Namespace="atom")]
public AtomLink AtomLink { get; set; }
[...]
Run Code Online (Sandbox Code Playgroud)
但输出是:
<link xmlns="atom" href="http://dallas.example.com/rss.xml" rel="self" type="application/rss+xml" />
Run Code Online (Sandbox Code Playgroud)
那么生成前缀标签的正确方法是什么?