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