none
Xml反序列化问题 RRS feed

  • 问题

  • <kml xmlns=" http://www.opengis.net/kml/2.2"><?xml version="1.0" encoding="utf-8"?>
    <kml xmlns=" http://www.opengis.net/kml/2.2">
    ...
    </kml>
    这一个标注的kml文件内容,使用相应的kml类,进行反序列化时提示 "不应有 <kml xmlns='http://www.opengis.net/kml/2.2'>。"。把xmlns='http://www.opengis.net/kml/2.2'去掉后就能够反序列化成功,请问应该怎么办。
    2010年12月21日 5:59

答案

  • 其实通过我给的连接,如果看完就应该知道什么情况了,xml也有命名空间的。我贴点代码出来吧(这些都是来自msdn)。

    注意这个部分

    [XmlRootAttribute("PurchaseOrder", Namespace="http://www.cpandl.com", 
    IsNullable = false)]
    
    

    这个是一个xml

    <?xml version="1.0" encoding="utf-8"?>
    <PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.cpandl.com">
      <ShipTo Name="Teresa Atkinson">
        <Line1>1 Main St.</Line1>
        <City>AnyTown</City>
        <State>WA</State>
        <Zip>00000</Zip>
      </ShipTo>
      <OrderDate>Wednesday, June 27, 2001</OrderDate>
      <Items>
        <OrderedItem>
          <ItemName>Widget S</ItemName>
          <Description>Small widget</Description>
          <UnitPrice>5.23</UnitPrice>
          <Quantity>3</Quantity>
          <LineTotal>15.69</LineTotal>
        </OrderedItem>
      </Items>
      <SubTotal>15.69</SubTotal>
      <ShipCost>12.51</ShipCost>
      <TotalCost>28.2</TotalCost>
    </PurchaseOrder>
    

     对应的代码:

    using System;
    using System.Xml;
    using System.Xml.Serialization;
    using System.IO;
    
    // The XmlRootAttribute allows you to set an alternate name 
    // (PurchaseOrder) for the XML element and its namespace. By 
    // default, the XmlSerializer uses the class name. The attribute 
    // also allows you to set the XML namespace for the element. Lastly,
    // the attribute sets the IsNullable property, which specifies whether 
    // the xsi:null attribute appears if the class instance is set to 
    // a null reference.
    [XmlRootAttribute("PurchaseOrder", Namespace="http://www.cpandl.com", 
    IsNullable = false)]
    public class PurchaseOrder
    {
      public Address ShipTo;
      public string OrderDate; 
      // The XmlArrayAttribute changes the XML element name
      // from the default of "OrderedItems" to "Items".
      [XmlArrayAttribute("Items")]
      public OrderedItem[] OrderedItems;
      public decimal SubTotal;
      public decimal ShipCost;
      public decimal TotalCost;  
    }
      
    public class Address
    {
      // The XmlAttribute instructs the XmlSerializer to serialize the 
      // Name field as an XML attribute instead of an XML element (the 
      // default behavior).
      [XmlAttribute]
      public string Name;
      public string Line1;
    
      // Setting the IsNullable property to false instructs the 
      // XmlSerializer that the XML attribute will not appear if 
      // the City field is set to a null reference.
      [XmlElementAttribute(IsNullable = false)]
      public string City;
      public string State;
      public string Zip;
    }
      
    public class OrderedItem
    {
      public string ItemName;
      public string Description;
      public decimal UnitPrice;
      public int Quantity;
      public decimal LineTotal;
    
      // Calculate is a custom method that calculates the price per item
      // and stores the value in a field.
      public void Calculate()
      {
        LineTotal = UnitPrice * Quantity;
      }
    }
      
    public class Test
    {
      public static void Main()
      {
        // Read and write purchase orders.
        Test t = new Test();
        t.CreatePO("po.xml");
        t.ReadPO("po.xml");
      }
    
      private void CreatePO(string filename)
      {
        // Creates an instance of the XmlSerializer class;
        // specifies the type of object to serialize.
        XmlSerializer serializer = 
        new XmlSerializer(typeof(PurchaseOrder));
        TextWriter writer = new StreamWriter(filename);
        PurchaseOrder po=new PurchaseOrder();
         
        // Creates an address to ship and bill to.
        Address billAddress = new Address();
        billAddress.Name = "Teresa Atkinson";
        billAddress.Line1 = "1 Main St.";
        billAddress.City = "AnyTown";
        billAddress.State = "WA";
        billAddress.Zip = "00000";
        // Sets ShipTo and BillTo to the same addressee.
        po.ShipTo = billAddress;
        po.OrderDate = System.DateTime.Now.ToLongDateString();
      
        // Creates an OrderedItem.
        OrderedItem i1 = new OrderedItem();
        i1.ItemName = "Widget S";
        i1.Description = "Small widget";
        i1.UnitPrice = (decimal) 5.23;
        i1.Quantity = 3;
        i1.Calculate();
      
        // Inserts the item into the array.
        OrderedItem [] items = {i1};
        po.OrderedItems = items;
        // Calculate the total cost.
        decimal subTotal = new decimal();
        foreach(OrderedItem oi in items)
        {
          subTotal += oi.LineTotal;
        }
        po.SubTotal = subTotal;
        po.ShipCost = (decimal) 12.51; 
        po.TotalCost = po.SubTotal + po.ShipCost; 
        // Serializes the purchase order, and closes the TextWriter.
        serializer.Serialize(writer, po);
        writer.Close();
      }
      
      protected void ReadPO(string filename)
      {
        // Creates an instance of the XmlSerializer class;
        // specifies the type of object to be deserialized.
        XmlSerializer serializer = new XmlSerializer(typeof(PurchaseOrder));
        // If the XML document has been altered with unknown 
        // nodes or attributes, handles them with the 
        // UnknownNode and UnknownAttribute events.
        serializer.UnknownNode+= new 
        XmlNodeEventHandler(serializer_UnknownNode);
        serializer.UnknownAttribute+= new 
        XmlAttributeEventHandler(serializer_UnknownAttribute);
      
        // A FileStream is needed to read the XML document.
        FileStream fs = new FileStream(filename, FileMode.Open);
        // Declares an object variable of the type to be deserialized.
        PurchaseOrder po;
        // Uses the Deserialize method to restore the object's state 
        // with data from the XML document. */
        po = (PurchaseOrder) serializer.Deserialize(fs);
        // Reads the order date.
        Console.WriteLine ("OrderDate: " + po.OrderDate);
      
        // Reads the shipping address.
        Address shipTo = po.ShipTo;
        ReadAddress(shipTo, "Ship To:");
        // Reads the list of ordered items.
        OrderedItem [] items = po.OrderedItems;
        Console.WriteLine("Items to be shipped:");
        foreach(OrderedItem oi in items)
        {
          Console.WriteLine("\t"+
          oi.ItemName + "\t" + 
          oi.Description + "\t" +
          oi.UnitPrice + "\t" +
          oi.Quantity + "\t" +
          oi.LineTotal);
        }
        // Reads the subtotal, shipping cost, and total cost.
        Console.WriteLine(
        "\n\t\t\t\t\t Subtotal\t" + po.SubTotal + 
        "\n\t\t\t\t\t Shipping\t" + po.ShipCost + 
        "\n\t\t\t\t\t Total\t\t" + po.TotalCost
        );
      }
      
      protected void ReadAddress(Address a, string label)
      {
        // Reads the fields of the Address.
        Console.WriteLine(label);
        Console.Write("\t"+
        a.Name +"\n\t" +
        a.Line1 +"\n\t" +
        a.City +"\t" +
        a.State +"\n\t" +
        a.Zip +"\n");
      }
    
      protected void serializer_UnknownNode
      (object sender, XmlNodeEventArgs e)
      {
        Console.WriteLine("Unknown Node:" +  e.Name + "\t" + e.Text);
      }
    
      protected void serializer_UnknownAttribute
      (object sender, XmlAttributeEventArgs e)
      {
        System.Xml.XmlAttribute attr = e.Attr;
        Console.WriteLine("Unknown attribute " + 
        attr.Name + "='" + attr.Value + "'");
      }
    }
    

    family as water
    2010年12月23日 2:02

全部回复

  • 对象加上这个标记(属性,命名空间)就好了。这样就能反序列化。

    参考:

    http://msdn.microsoft.com/zh-cn/library/system.xml.serialization.xmlserializer(v=VS.80).aspx


    family as water
    2010年12月21日 9:10
  • Hi Stone Z,

    可否将您的答案描述的详细一些,我也对这个问题很感兴趣。
    谢谢。

    Sincerely,
    Leo Liu
    Leo Liu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2010年12月23日 1:49
    版主
  • 其实通过我给的连接,如果看完就应该知道什么情况了,xml也有命名空间的。我贴点代码出来吧(这些都是来自msdn)。

    注意这个部分

    [XmlRootAttribute("PurchaseOrder", Namespace="http://www.cpandl.com", 
    IsNullable = false)]
    
    

    这个是一个xml

    <?xml version="1.0" encoding="utf-8"?>
    <PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.cpandl.com">
      <ShipTo Name="Teresa Atkinson">
        <Line1>1 Main St.</Line1>
        <City>AnyTown</City>
        <State>WA</State>
        <Zip>00000</Zip>
      </ShipTo>
      <OrderDate>Wednesday, June 27, 2001</OrderDate>
      <Items>
        <OrderedItem>
          <ItemName>Widget S</ItemName>
          <Description>Small widget</Description>
          <UnitPrice>5.23</UnitPrice>
          <Quantity>3</Quantity>
          <LineTotal>15.69</LineTotal>
        </OrderedItem>
      </Items>
      <SubTotal>15.69</SubTotal>
      <ShipCost>12.51</ShipCost>
      <TotalCost>28.2</TotalCost>
    </PurchaseOrder>
    

     对应的代码:

    using System;
    using System.Xml;
    using System.Xml.Serialization;
    using System.IO;
    
    // The XmlRootAttribute allows you to set an alternate name 
    // (PurchaseOrder) for the XML element and its namespace. By 
    // default, the XmlSerializer uses the class name. The attribute 
    // also allows you to set the XML namespace for the element. Lastly,
    // the attribute sets the IsNullable property, which specifies whether 
    // the xsi:null attribute appears if the class instance is set to 
    // a null reference.
    [XmlRootAttribute("PurchaseOrder", Namespace="http://www.cpandl.com", 
    IsNullable = false)]
    public class PurchaseOrder
    {
      public Address ShipTo;
      public string OrderDate; 
      // The XmlArrayAttribute changes the XML element name
      // from the default of "OrderedItems" to "Items".
      [XmlArrayAttribute("Items")]
      public OrderedItem[] OrderedItems;
      public decimal SubTotal;
      public decimal ShipCost;
      public decimal TotalCost;  
    }
      
    public class Address
    {
      // The XmlAttribute instructs the XmlSerializer to serialize the 
      // Name field as an XML attribute instead of an XML element (the 
      // default behavior).
      [XmlAttribute]
      public string Name;
      public string Line1;
    
      // Setting the IsNullable property to false instructs the 
      // XmlSerializer that the XML attribute will not appear if 
      // the City field is set to a null reference.
      [XmlElementAttribute(IsNullable = false)]
      public string City;
      public string State;
      public string Zip;
    }
      
    public class OrderedItem
    {
      public string ItemName;
      public string Description;
      public decimal UnitPrice;
      public int Quantity;
      public decimal LineTotal;
    
      // Calculate is a custom method that calculates the price per item
      // and stores the value in a field.
      public void Calculate()
      {
        LineTotal = UnitPrice * Quantity;
      }
    }
      
    public class Test
    {
      public static void Main()
      {
        // Read and write purchase orders.
        Test t = new Test();
        t.CreatePO("po.xml");
        t.ReadPO("po.xml");
      }
    
      private void CreatePO(string filename)
      {
        // Creates an instance of the XmlSerializer class;
        // specifies the type of object to serialize.
        XmlSerializer serializer = 
        new XmlSerializer(typeof(PurchaseOrder));
        TextWriter writer = new StreamWriter(filename);
        PurchaseOrder po=new PurchaseOrder();
         
        // Creates an address to ship and bill to.
        Address billAddress = new Address();
        billAddress.Name = "Teresa Atkinson";
        billAddress.Line1 = "1 Main St.";
        billAddress.City = "AnyTown";
        billAddress.State = "WA";
        billAddress.Zip = "00000";
        // Sets ShipTo and BillTo to the same addressee.
        po.ShipTo = billAddress;
        po.OrderDate = System.DateTime.Now.ToLongDateString();
      
        // Creates an OrderedItem.
        OrderedItem i1 = new OrderedItem();
        i1.ItemName = "Widget S";
        i1.Description = "Small widget";
        i1.UnitPrice = (decimal) 5.23;
        i1.Quantity = 3;
        i1.Calculate();
      
        // Inserts the item into the array.
        OrderedItem [] items = {i1};
        po.OrderedItems = items;
        // Calculate the total cost.
        decimal subTotal = new decimal();
        foreach(OrderedItem oi in items)
        {
          subTotal += oi.LineTotal;
        }
        po.SubTotal = subTotal;
        po.ShipCost = (decimal) 12.51; 
        po.TotalCost = po.SubTotal + po.ShipCost; 
        // Serializes the purchase order, and closes the TextWriter.
        serializer.Serialize(writer, po);
        writer.Close();
      }
      
      protected void ReadPO(string filename)
      {
        // Creates an instance of the XmlSerializer class;
        // specifies the type of object to be deserialized.
        XmlSerializer serializer = new XmlSerializer(typeof(PurchaseOrder));
        // If the XML document has been altered with unknown 
        // nodes or attributes, handles them with the 
        // UnknownNode and UnknownAttribute events.
        serializer.UnknownNode+= new 
        XmlNodeEventHandler(serializer_UnknownNode);
        serializer.UnknownAttribute+= new 
        XmlAttributeEventHandler(serializer_UnknownAttribute);
      
        // A FileStream is needed to read the XML document.
        FileStream fs = new FileStream(filename, FileMode.Open);
        // Declares an object variable of the type to be deserialized.
        PurchaseOrder po;
        // Uses the Deserialize method to restore the object's state 
        // with data from the XML document. */
        po = (PurchaseOrder) serializer.Deserialize(fs);
        // Reads the order date.
        Console.WriteLine ("OrderDate: " + po.OrderDate);
      
        // Reads the shipping address.
        Address shipTo = po.ShipTo;
        ReadAddress(shipTo, "Ship To:");
        // Reads the list of ordered items.
        OrderedItem [] items = po.OrderedItems;
        Console.WriteLine("Items to be shipped:");
        foreach(OrderedItem oi in items)
        {
          Console.WriteLine("\t"+
          oi.ItemName + "\t" + 
          oi.Description + "\t" +
          oi.UnitPrice + "\t" +
          oi.Quantity + "\t" +
          oi.LineTotal);
        }
        // Reads the subtotal, shipping cost, and total cost.
        Console.WriteLine(
        "\n\t\t\t\t\t Subtotal\t" + po.SubTotal + 
        "\n\t\t\t\t\t Shipping\t" + po.ShipCost + 
        "\n\t\t\t\t\t Total\t\t" + po.TotalCost
        );
      }
      
      protected void ReadAddress(Address a, string label)
      {
        // Reads the fields of the Address.
        Console.WriteLine(label);
        Console.Write("\t"+
        a.Name +"\n\t" +
        a.Line1 +"\n\t" +
        a.City +"\t" +
        a.State +"\n\t" +
        a.Zip +"\n");
      }
    
      protected void serializer_UnknownNode
      (object sender, XmlNodeEventArgs e)
      {
        Console.WriteLine("Unknown Node:" +  e.Name + "\t" + e.Text);
      }
    
      protected void serializer_UnknownAttribute
      (object sender, XmlAttributeEventArgs e)
      {
        System.Xml.XmlAttribute attr = e.Attr;
        Console.WriteLine("Unknown attribute " + 
        attr.Name + "='" + attr.Value + "'");
      }
    }
    

    family as water
    2010年12月23日 2:02
  • 你好!

        你两个同名的元素的命名空间重名了,出现了冲突。修改其中一个就可以了。


    周雪峰
    2010年12月23日 13:13
    版主
  • 谢谢大家的热心。
    2010年12月28日 9:02