VB.NET反序列化含命名空间前缀的AIXM格式XML问题求解
VB.NET 带命名空间前缀XML反序列化适配方案
问题背景
对包含message:、aixm:、xlink:、gml:等命名空间前缀的AIXM格式XML执行反序列化时,现有实体类未配置命名空间映射导致匹配失败,手动删除前缀后可正常执行,需在不修改原XML文件的前提下完成适配。
根因
XmlSerializer 做节点匹配时,会同时校验元素/属性的本地名称和所属命名空间URI,现有代码仅配置了本地名称,未指定各前缀对应的命名空间,导致带前缀的节点无法和实体类属性匹配。
AIXM 5.1.1版本默认命名空间映射如下,若使用其他版本,可直接查看XML根节点上的xmlns:前缀="URI"声明取实际值:
message对应URI:http://www.aixm.aero/schema/5.1.1/messagegml对应URI:http://www.opengis.net/gml/3.2xlink对应URI:http://www.w3.org/1999/xlinkaixm对应URI:http://www.aixm.aero/schema/5.1.1
适配步骤
- 移除原有多余的
Root类,原XML根节点就是AIXMBasicMessage,额外嵌套一层映射反而会匹配失败。 - 给所有
XmlRoot、XmlElement、XmlAttribute特性补充Namespace参数,映射到对应URI,同时补充原代码遗漏的gml:id属性映射。
修改后完整代码
' 统一维护命名空间常量,可根据实际XML里的xmlns声明替换值 Public Const NS_MESSAGE As String = "http://www.aixm.aero/schema/5.1.1/message" Public Const NS_GML As String = "http://www.opengis.net/gml/3.2" Public Const NS_XLINK As String = "http://www.w3.org/1999/xlink" Public Const NS_AIXM As String = "http://www.aixm.aero/schema/5.1.1" <XmlRoot(ElementName:="hasMember", Namespace:=NS_MESSAGE)> Public Class HasMember <XmlElement(ElementName:="VerticalStructure", Namespace:=NS_AIXM)> Public Property VerticalStructure As VerticalStructure <XmlAttribute(AttributeName:="type", Namespace:=NS_XLINK)> Public Property Type As String ' 补充原代码遗漏的gml:id属性映射 <XmlAttribute(AttributeName:="id", Namespace:=NS_GML)> Public Property GmlId As String <XmlText> Public Property Text As String End Class <XmlRoot(ElementName:="VerticalStructure", Namespace:=NS_AIXM)> Public Class VerticalStructure ' 补充gml:id属性映射 <XmlAttribute(AttributeName:="id", Namespace:=NS_GML)> Public Property GmlId As String ' 类内部其他属性按相同规则补充Namespace配置即可 End Class <XmlRoot(ElementName:="AIXMBasicMessage", Namespace:=NS_MESSAGE)> Public Class AIXMBasicMessage <XmlElement(ElementName:="hasMember", Namespace:=NS_MESSAGE)> Public Property HasMember As List(Of HasMember) ' 补充原代码遗漏的gml:id属性映射 <XmlAttribute(AttributeName:="id", Namespace:=NS_GML)> Public Property GmlId As String End Class
反序列化调用示例
' 直接以AIXMBasicMessage作为根类型反序列化,不需要额外的命名空间预处理 Dim serializer As New XmlSerializer(GetType(AIXMBasicMessage)) Using fs As New FileStream("你的XML文件路径.xml", FileMode.Open) Dim aixmMessage As AIXMBasicMessage = CType(serializer.Deserialize(fs), AIXMBasicMessage) ' 执行业务逻辑 End Using
注意事项
XmlSerializer按命名空间URI做匹配,和前缀字符串无关,哪怕原XML把message前缀改成其他自定义字符串,只要URI和配置一致就可以正常反序列化。- 如果XML使用的AIXM版本和示例不同,只需要替换最上方命名空间常量为你XML根节点
xmlns声明里的对应URI即可,其他代码不需要改动。 VerticalStructure类内部的其他子节点,只要带aixm:前缀就配置Namespace:=NS_AIXM,带gml:前缀的属性配置Namespace:=NS_GML即可。
内容的提问来源于stack exchange,提问作者jpi76
相关产品推荐
相关产品推荐

