标签: xmlserializer

内存泄漏使用StreamReader和XmlSerializer

我一直在谷歌搜索过去几个小时并尝试不同的东西,但似乎不能在这个底部....

当我运行此代码时,内存使用量不断增长.

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(); 但这似乎没有做任何事情.

c# xml streamreader xmlserializer

24
推荐指数
4
解决办法
1万
查看次数

使用XmlSerializer创建具有属性和值但没有子元素的元素

希望对于那里的人(可能是一个骗子)来说这应该是一个简单的答案,但我似乎无法弄明白.

我需要输出一个如下所示的元素:

<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,我会非常惊讶,但我还不知道.有任何想法吗?

c# xmlserializer

23
推荐指数
1
解决办法
1万
查看次数

当属性具有xlink命名空间时,Chrome 22会输出无效的XML

我有以下最小的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)

javascript google-chrome xmlserializer

23
推荐指数
1
解决办法
1898
查看次数

XmlSerializer在64位系统上启动巨大的性能损失

我在一个有很多字段的类上调用一个简单的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错误所牵制,请不要阅读此内容.

  • 从Visual Studio调试器运行代码使代码即使在64位系统中也能运行FAST
  • 添加(完全未记录的)system.diagnostic开关"XmlSerialization.Compile",防止系统删除序列化临时类,使代码即使在64位系统中运行也很快
  • 获取运行时创建的临时FooXmlSerializer类,包括我项目中的.cs,并使用它代替XmlSerializer,使得代码即使在64位系统中运行也很快
  • 使用sgen.exe创建相同的FooXmlSerializer类,包括我的项目中的.cs,并使用它而不是XmlSerializer,使代码即使在64位系统中运行也很快
  • 使用sgen.exe创建相同的FooXmlSerializer类,在我的项目中引用Foo.XmlSerializers.dll程序集,并使用它而不是XmlSerializer,使得代码在64位系统中运行缓慢(这让我很烦恼)
  • 如果反序列化的输入实际上包含一个大类的字段(这也让我很烦),只会发生性能损失

为了进一步解释最后一点,如果我有一个班级:

[Serializable]
class Bar
{ …
Run Code Online (Sandbox Code Playgroud)

.net 64-bit xmlserializer

22
推荐指数
2
解决办法
6089
查看次数

如何XML序列化字典

我已经能够以这种方式序列化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).

我怎样才能做到这一点?

.net c# xml-serialization xmlserializer

20
推荐指数
4
解决办法
6万
查看次数

使用XmlSerializer时如何在XML文件中写注释?

我有一个对象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文件,我可以这样做,但是我可以实现可能的属性或替代语法,以便我可以继续使用序列化程序功能吗?

.net c# xml xml-serialization xmlserializer

20
推荐指数
2
解决办法
1万
查看次数

ShouldSerialize*()vs*指定的条件序列化模式

我知道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)

.net c# serialization xml-serialization xmlserializer

19
推荐指数
2
解决办法
7851
查看次数

XmlSerializer.Deserialize List <>项目

我已经尝试了所有可以在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)

c# serialization xmlserializer

18
推荐指数
1
解决办法
1万
查看次数

如何使用XMLSerializer添加没有前缀的默认命名空间

我正在尝试生成一个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)

c# namespaces xmlserializer

18
推荐指数
1
解决办法
2万
查看次数

如何使用XmlSerializer生成标记前缀

我想使用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)

那么生成前缀标签的正确方法是什么?

c# xmlserializer

18
推荐指数
1
解决办法
3万
查看次数