2010-03-04 23 views
1

我有包含我想反序列化到C#以下格式的XML的Stream对象为什么XmlReader将名称空间uris附加到每个元素?

<?xml version="1.0" encoding="utf-8" standalone="yes"?> 
<OrganisationMetaData xmlns="urn:organisationMetaDataSchema"> 
    <Organisations> 
    <Organisation> 
     <Code>XXX</Code> 
     <Name>Yyyyyy</Name>... 

我做这个负载与串倍,但与流是好心附加的命名空间属性到所有复杂的元素。如果我只是删除了xmlns属性,而忘记了根据模式对它进行验证,它只会附加一个空的xmlns属性。我遇到的问题是XmlSerializer(?)中的Deserialize方法会抛出一个错误,指出它不指望该属性。我尝试用XmlRoot和XmlType属性装饰类,但是这并没有改变任何东西。

这是我想反序列化到

[XmlRoot(
    ElementName = "OrganisationMetaData", 
    Namespace = "urn:organisationMetaDataSchema")] 
public class OrganisationMetaData 
{ 
    public List<Organisation> Organisations { get; set; } 
} 

[XmlType(
    TypeName = "Organisation", 
    Namespace = "urn:organisationMetaDataSchema")] 
public class Organisation 
{ 
    public string Code {get; set;} 

    public string Name {get; set;} 
} 

这里类的正在使用做的工作

public IList<Organisation> DeserializeOrganisations(Stream stream) 
    { 
     var serializer = new XmlSerializer(typeof(OrganisationMetaData)); 

     var mappingAssembly = //Resource in another assembly 

     var schemas = new XmlSchemaSet(); 
     schemas.Add(
      "urn:organisationMetaDataSchema", 
      XmlReader.Create(
       mappingAssembly.GetManifestResourceStream(
        // An xml schema 
        ) 
       ) 
      ); 
     var settings = new XmlReaderSettings() 
          { 
           ValidationType = ValidationType.Schema, 
           Schemas = schemas, 
           ValidationFlags = 
        XmlSchemaValidationFlags.ReportValidationWarnings 
          };    

     settings.ValidationEventHandler += settings_ValidationEventHandler; 
     var reader = XmlReader.Create(stream, settings); 

     var metaData= (OrganisationMetaData)serializer.Deserialize(reader); 
     return metaData.Organisations.ToList(); 
    } 

我已经试过这一点使用的DataContractSerializer方法,但带来它自己的[商机学习,所以如果任何人都可以帮助我应该把属性放在XmlSerializer的属性上,那就太好了。

任何帮助,将不胜感激,谢谢。

回答

0

我最终改变使用数据契约的代码序列化程序,它给了我更多关于命名空间的明显错误,使我可以让读者根据模式验证xml流,然后倒回流并在另一个读取器中重新使用它来反序列化xml。

阅读this question提醒我一个需要xml元素按字母顺序排列的漏洞。我还发现,当反序列化我的类的属性是一个枚举时,我需要要求它存在(毕竟它不是空的)。

然后,这导致了另一个错误,我有一个xml节点,省略了一些值(由我的模式确定),但数据协定期望这些按顺序排列,因此我必须明确指定。

我结束了一个数据成员属性这样

[DataMember(
     Name = "MyEnumType", 
     EmitDefaultValue = false, 
     IsRequired = true, 
     Order = 3)] 
//Just assume I added this prop after my Code, and Name properties from above 

感谢马克抽出时间来看看这个。

1

这里的关键是[XmlRoot]只能应用于根类型,如类;如果您使用的是List<>作为根目录,则不起作用 - 但我们可以通过[XmlElement]来补足。我使用的是Stream方法(通过Encoding.UTF8),但请注意,这不是真正的问题的心脏IMO(根类型):

[XmlRoot(Namespace="urn:organisationMetaDataSchema")] 
public class Organisations 
{ 
    private readonly List<Organisation> items = new List<Organisation>(); 
    [XmlElement("Organisation")] 
    public List<Organisation> Items { get { return items; } } 

} 
public class Organisation 
{ 
    public string Code { get; set; } 
    public string Name { get; set; } 
} 
static class Program 
{ 
    static void Main() 
    { 
     string xml = @"<?xml version='1.0' encoding='utf-8' standalone='yes'?><Organisations xmlns='urn:organisationMetaDataSchema'><Organisation><Code>XXXX</Code><Name>YYYYYYYY</Name></Organisation></Organisations>"; 
     XmlSerializer ser = new XmlSerializer(typeof(Organisations)); 
     using (Stream input = new MemoryStream(Encoding.UTF8.GetBytes(xml))) 
     { 
      Organisations orgs = (Organisations)ser.Deserialize(input); 
     } 
    } 
} 
+0

谢谢马克,我现在对此有点脑衰。我的xml没有你的字符串所具有的单引号。你将如何克服这个,像Replace(...)这样简单的事情? – 2010-03-04 12:24:59

+0

我已经尝试过所有我能想到的东西,所以大约8个小时后,我已经放弃了DataContractSerializer,而在东方可以告诉我更多关于xml不喜欢的内容。感谢您的帮助Marc :) – 2010-03-04 15:04:25

+0

@Mark - 单引号无关紧要。发布的代码应该反序列化你引用的xml。你可以发布(或电子邮件,如果你喜欢)你的课程?我很确定我可以告诉你什么是错的... – 2010-03-04 16:34:26

相关问题