2012-07-26 38 views
1


我的XML序列化程序有一个奇怪的行为。
读取XML并将其反序列化为对象后,所有属性都设置为默认值,而不是xml文件中声明的值。
序列化程序不会引发异常并正常运行。 xml文件格式正确,适合类结构。
任何人的想法如何,或我如何能找到问题的根源?
谢谢XML反序列化:对象具有默认值

编辑: 我没有告诉你整个故事。事情是,我得到的XML是来自另一个组件。我能够反序列化XML文件,现在我得到了不同的格式。由于该文件有大约3000行,我无法发布整个代码。但这里的区别:
deserializable:

<?xml version="1.0" encoding="utf-8"?>
<rootElem xmlns:cfg="namespace1" xmlns:office="namespace2" xmlns="namespace3">
<Prop1 xmlns="">6</Prop1>
<Prop2 xmlns="">string</Prop2>
</rootElem>

不deserializable

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rootElem xmlns:cfg="namespace1" xmlns:office="namespace2" xmlns="namespace3">
<Prop1>6</Prop1>
<Prop2>string</Prop2>
</rootElem>

我真的不明白,为什么我可以解编第一个例子,由于XMLNS标签内每个元素,为什么我不能解组第二个...

EDIT2:刚刚意识到这只是顶级元素有这些奇怪的xmlns = “” 属性。但是C#类声明与其他所有类没有什么不同......这很奇怪。

的C#类是这样的:

using namespace1; 

namespace namespace3 
{ 
    [System.SerializableAttribute()] 
    [System.ComponentModel.DesignerCategoryAttribute("code")] 
    [System.Xml.Serialization.XmlTypeAttribute(Namespace="namespace3")] 
    [System.Xml.Serialization.XmlRootAttribute(Namespace="namespace3", IsNullable=true)] 
    public partial class rootElem: BaseObject 
    { 
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] 
    public int Prop1 
    { 
     //... 
    } 
    } 
} 
+0

您需要提供更多的信息,最好是相关代码段与你正在反序列化。 – ipavlic 2012-07-26 07:08:36

+0

@ipavlic更新了问题并添加了一个示例 – derape 2012-07-26 07:28:06

回答

1

一个具体的例子(包括C#广告XML)将何去何从很长的路要走。最有可能的一个:

  • 名字都没有的XML和C#之间的确切(区分大小写)匹配
  • 有XML属性之间的mixup(通过属性等,允许名称覆盖)/元素
  • 没有在XML命名空间(通常存在于XML和失踪的C#)的差异

随着你的编辑,它变得更清晰。 Xml命名空间为非常有效; <foo xmlns="abc"/><foo/>是完全无关的。此外,XML命名空间是继承,所以在:

<rootElem xmlns:cfg="namespace1" xmlns:office="namespace2" xmlns="namespace3"> 
<Prop1>6</Prop1> 
<Prop2>string</Prop2> 
</rootElem> 

它是Prop1Prop2都在namespace3命名空间,他们从他们的父母继承的情况。为了使这是绝对清楚的是,你想那些要在孩子命名空间(而不是空的命名空间)的C#,告诉它

[Serializable] 
[DesignerCategory("code")] 
[XmlType(Namespace = Namespace3)] 
[XmlRoot(Namespace = Namespace3, IsNullable = true)] 
public partial class rootElem 
{ 
    private const string Namespace3 = "namespace3"; // to avoid repetition 

    [XmlElement(Namespace = Namespace3)] 
    public int Prop1 { get; set; } 
} 
+0

感谢提示。我更新了我的问题,所以我想它与xml语法有关,因为c#类和模式已经被更改... – derape 2012-07-26 07:50:39

+1

@derape这实际上是第3个项目符号;将编辑添加更多 – 2012-07-26 07:58:37

+0

你认为这是问题,我将不得不明确声明它?因为这些类是从XSD生成的,所以我需要修改代... – derape 2012-07-26 08:17:57

0

经过进一步调查,我能够发现问题。我仍然不明白为什么序列化器的行为方式如此。 据我了解命名空间的decleration你必须定义“xmlns”属性没有前缀设置默认命名空间(W3Schools)。正如我的问题说,它被定义(除了其他命名空间):

<rootElem xmlns:cfg="namespace1" xmlns:office="namespace2" xmlns="namespace3"> 

因为根元素的所有直接孩子们xmlns属性(再次)宣布,我的解释是,默认的命名空间不能找到。
所以我所做的就是要明确地定义一个命名空间的根元素,这样的根元素是这样产生的:

<root:rootElem xmlns:cfg="namespace1" xmlns:office="namespace2" xmlns:root="namespace3"> 

瞧,是正确生成的XML(从直接移除xmlns属性儿童)和串行器能够读取数据。
但还是有些问题依然存在:

  • 为什么串行无法正常使用默认的 命名空间生成XML?
  • 我期望的异常,如果串行无法读取数据,并把它放到我的实例(为什么要创建一个“空”的情况下)