XMl 序列化的小问题

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

<kml xmlns="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文件如下 :

<?xml version="1.0" encoding="UTF-8"?>
<kml  xmlns: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# 进行选取元素

XmlDocument xml = new XmlDocument();
xml.Load(@"D:\Documents\Visual Studio 2013\Projects\WindowsFormsApplication1\WindowsFormsApplication1\中牟站.kml");

// XPath

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

调试下的结果 :

163441_lJqC_559187.png

 

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

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

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

[Serializable]
public class Company
{

 [XmlElement]
 public int Count { get; set; }
 [XmlElement]
 public List<Person> PersonList { get; set; }
 [XmlElement]
 public Person Leader { get; set; }
}

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

<?xml version="1.0"?>
<Company xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Count>5</Count>
  <PersonList>
    <Name>MISS DD</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>MRS DDL</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 类型的,但是由于代码中指定成了元素,所以就少了一层嵌套。因为没搞明白多加的声明反而画蛇添足了,所以只要去掉或者换成正确的特性声明就会回归正常的输出。

<?xml version="1.0"?>
<Company xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Count>5</Count>
  <PersonList>
    <Person>
      <Name>MISS DD</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>MRS DDL</Name>
    <Age>23</Age>
    <Sex>Unknow</Sex>
    <Direction>Right</Direction>
  </Leader>
</Company>

 

 

转载于:https://my.oschina.net/HenuToater/blog/349502

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值