加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

XMl 序列化的小问题

发布时间:2020-12-16 09:25:30 所属栏目:百科 来源:网络整理
导读:Google Earth 中 KML 文件都采用了下面的属性定义 kmlxmlns="http://www.opengis.net/kml/2.2"xmlns:gx="http://www.google.com/kml/ext/2.2"xmlns:kml="http://www.opengis.net/kml/2.2"xmlns:atom="http://www.w3.org/2005/Atom" 其中第三个名称空间的前缀

Google Earth 中 KML 文件都采用了下面的属性定义

<kmlxmlns="http://www.opengis.net/kml/2.2"xmlns:gx="http://www.google.com/kml/ext/2.2"

xmlns:kml="http://www.opengis.net/kml/2.2"xmlns:atom="http://www.w3.org/2005/Atom">

其中第三个名称空间的前缀名为 kml 与当前元素的标签名相同,这样在使用 XPath 语法选择子元素等操作时一直返回为NULL

不知道 Google 最初为社么这样设计的,但在 C# 语言中使用 XmlDocument 的 读取时无法正确读出来。

测试的KML文件如下 :

<?xmlversion="1.0"encoding="UTF-8"?>
<kmlxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:kml="http://www.opengis.net/kml/2.2">
<Document>
<Placemark>
<name>中牟站</name>
<styleUrl>#m_ylw-pushpin16</styleUrl>
<Polygon>
<tessellate>1</tessellate>
<outerBoundaryIs>
<LinearRing>
<coordinates>
114.0181288105562,34.70732579930824,0
114.0182028197397,34.70717842472297,0
114.0191556334107,34.70729121976968,0
</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
</Document>
</kml>

然后使用 C# 进行选取元素

XmlDocumentxml=newXmlDocument();
xml.Load(@"D:DocumentsVisualStudio2013ProjectsWindowsFormsApplication1WindowsFormsApplication1中牟站.kml");

//XPath

XmlNodeListnodes=xml.SelectNodes("/kml/Document/Placemark");

调试下的结果 :

在调试的时候发现使用 FirstChild 和 LastChild 可以正确地访问 根节点 <kml>,但是进入子节点后就不能识别了,表示好郁闷

第一次碰到这个问题的时候不想仔细去想就直接干kml节点了,今天再碰到就表示不能什么都归结于人品问题吧。认真一下就发现这个 xmlns:kml 定义竟然跟节点名称一样,是XMl的标准不允许这样的语法,还是Google的疏忽?

现在有一个包含复杂元素的类需要序列化

[Serializable]
publicclassCompany
{

[XmlElement]
publicintCount{get;set;}
[XmlElement]
publicList<Person>PersonList{get;set;}
[XmlElement]
publicPersonLeader{get;set;}
}

可以是序列化后发现有一个小问题

<?xmlversion="1.0"?>
<Companyxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Count>5</Count>
<PersonList>
<Name>MISSDD</Name>
<Age>20</Age>
<Sex>Female</Sex>
<Direction>Left</Direction>
</PersonList>
<PersonList>
<Name>MR.DD</Name>
<Age>19</Age>
<Sex>Male</Sex>
<Direction>Right</Direction>
</PersonList>
<Leader>
<Name>MRSDDL</Name>
<Age>23</Age>
<Sex>Unknow</Sex>
<Direction>Right</Direction>
</Leader>
</Company>

第二个属性 PersonList 没有正确地嵌套层次关系,它的子元素直接当作类的属性输出了,是什么原因导致的?仔细实验了一下,原来是属性定义时使用了错误的XML特性声明。

XmlElementAttribute

指示公共字段或属性在 System.Xml.Serialization.XmlSerializer 序列化或反序列化包含它们的对象时表示 XML元素。

XmlArrayAttribute

指定 System.Xml.Serialization.XmlSerializer 必须将特定的类成员序列化为 XML 元素的数组。

XmlArrayItem

表示指定 System.Xml.Serialization.XmlSerializer 可以放置在序列化数组中的派生类型的特性。

XmlAttribute

指定 System.Xml.Serialization.XmlSerializer 必须将类成员序列化为 XML 特性。

正是由于对这几个特性声明对应的含义不了解导致的错误。本来我们的集合元素 PersonList 应该是 XmlArray 类型的,但是由于代码中指定成了元素,所以就少了一层嵌套。因为没搞明白多加的声明反而画蛇添足了,所以只要去掉或者换成正确的特性声明就会回归正常的输出。

<?xmlversion="1.0"?>
<Companyxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Count>5</Count>
<PersonList>
<Person>
<Name>MISSDD</Name>
<Age>20</Age>
<Sex>Female</Sex>
<Direction>Left</Direction>
</Person>
<Person>
<Name>MR.DD</Name>
<Age>19</Age>
<Sex>Male</Sex>
<Direction>Right</Direction>
</Person>
</PersonList>
<Leader>
<Name>MRSDDL</Name>
<Age>23</Age>
<Sex>Unknow</Sex>
<Direction>Right</Direction>
</Leader>
</Company>

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读