Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么XmlReader要将命名空间URI附加到每个元素?_C#_Xml_Serialization_Xmlreader_Xmlserializer - Fatal编程技术网

C# 为什么XmlReader要将命名空间URI附加到每个元素?

C# 为什么XmlReader要将命名空间URI附加到每个元素?,c#,xml,serialization,xmlreader,xmlserializer,C#,Xml,Serialization,Xmlreader,Xmlserializer,我有一个包含以下格式的xml的流,我想将其反序列化为C#objects 我已经用字符串多次这样做了,但是对于流,它会将namespace属性附加到所有复杂元素中。如果我只是删除xmlns属性,而忘记了根据模式验证它,那么它只会附加一个空的xmlns属性。我遇到的问题是XmlSerializer(?)中的反序列化方法抛出一个错误,表示它不需要该属性。我尝试过用XmlRoot和XmlType属性装饰这个类,但这并没有改变任何事情 这是我想要反序列化到的类 [XmlRoot( ElementNa

我有一个包含以下格式的xml的流,我想将其反序列化为C#objects

我已经用字符串多次这样做了,但是对于流,它会将namespace属性附加到所有复杂元素中。如果我只是删除xmlns属性,而忘记了根据模式验证它,那么它只会附加一个空的xmlns属性。我遇到的问题是XmlSerializer(?)中的反序列化方法抛出一个错误,表示它不需要该属性。我尝试过用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;}
}
[XmlRoot(
ElementName=“OrganizationMetadata”,
Namespace=“urn:OrganizationMetadataschema”)]
公共类组织元数据
{
公共列表组织{get;set;}
}
[XmlType(
TypeName=“组织”,
Namespace=“urn:OrganizationMetadataschema”)]
公营班级组织
{
公共字符串代码{get;set;}
公共字符串名称{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();
    }
公共IList反序列化组织(流)
{
var serializer=新的XmlSerializer(typeof(OrganizationMetadata));
var mappingAssembly=//另一个程序集中的资源
var schemase=new XmlSchemaSet();
架构。添加(
“urn:OrganizationMetadataschema”,
创建(
mappingAssembly.GetManifestResourceStream(
//xml模式
)
)
);
var设置=新的XmlReaderSettings()
{
ValidationType=ValidationType.Schema,
模式=模式,
验证标志=
XmlSchemaValidationFlags.ReportValidationWarnings
};            
settings.ValidationEventHandler+=设置\u ValidationEventHandler;
var reader=XmlReader.Create(流、设置);
变量元数据=(OrganizationMetadata)序列化程序。反序列化(读取器);
返回metaData.organizations.ToList();
}
我曾尝试使用DataContractSerializer来实现这一点,但这也带来了学习的机会,因此,如果有人能够帮助我在属性中添加什么,以使XmlSerializer正常工作,那就太好了


非常感谢您的帮助。

这里的关键是
[XmlRoot]
只能应用于根类型,例如类;如果您使用
列表
作为根目录,它将不起作用-但我们可以使用
[xmlement]
填充它。我使用的是
方法(通过
编码.UTF8
),但请注意,这并不是问题的核心(根类型是):


这里的关键是
[XmlRoot]
只能应用于根类型,例如类;如果您使用
列表
作为根目录,它将不起作用-但我们可以使用
[xmlement]
填充它。我使用的是
方法(通过
编码.UTF8
),但请注意,这并不是问题的核心(根类型是):


最后,我将代码更改为使用数据契约序列化程序,它在名称空间中给了我更明显的错误,允许我使用一个读卡器根据模式验证xml流,然后倒带该流并在另一个反序列化xml的读卡器中再次使用它

Reading提醒我,xml元素必须按字母顺序排列。我还发现,当反序列化属于枚举的类的属性时,我需要要求该属性存在(它毕竟不可为null)

这导致了另一个错误,我有一个省略了一些值的xml节点(根据我的模式确定),但是数据契约预期这些值是按顺序的,所以我必须显式地指定它

我最终得到了这样一个数据成员属性

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

感谢Marc花时间来研究这一点。

我最终将代码更改为使用数据契约序列化程序,它在名称空间方面给了我更明显的错误,允许我使用一个读卡器根据模式验证xml流,然后倒带该流,并在另一个反序列化xml的读卡器中再次使用它

Reading提醒我,xml元素必须按字母顺序排列。我还发现,当反序列化属于枚举的类的属性时,我需要要求该属性存在(它毕竟不可为null)

这导致了另一个错误,我有一个省略了一些值的xml节点(根据我的模式确定),但是数据契约预期这些值是按顺序的,所以我必须显式地指定它

我最终得到了这样一个数据成员属性

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

谢谢Marc花时间看了这篇文章。

谢谢Marc,我现在对这篇文章有点不耐烦了。我的xml没有字符串的单引号。如何克服这个问题,比如替换(…)?我已经尝试了我能想到的所有方法,所以在大约8个小时后,我放弃了,转而使用DataContractSerializer,这至少可以告诉我它不喜欢xml的地方。谢谢你的帮助,马克:)@Mark-单引号并不重要。发布的代码应该反序列化您引用的xml。你能把你的课发出去吗?我很确定我能告诉你出了什么问题……我这里有一些限制。发布代码,但我会拼凑一些东西,只是为了得到一个像样的答案。我发现的问题是,如果我将流放入字符串中,它在双引号、换行符和返回之前有转义字符。我不知道这些是从哪里来的。我已经开始使用DataContractSerialize
[DataMember(
        Name = "MyEnumType", 
        EmitDefaultValue = false, 
        IsRequired = true, 
        Order = 3)] 
//Just assume I added this prop after my Code, and Name properties from above