Xmlserializer - 控制元素 - 属性配对(修订)

时间:2009-04-08 23:48:02

标签: xml-serialization

XmlSerializer做了我想要的一切,只有一个例外。我需要将一个元素与另一个元素配对作为该元素的属性。我不想写一个完全自定义的序列化方法。这是我的班级:

public class Transaction
{
   [XmlElement("ID")]
   public int m_id;

   [XmlElement("TransactionType")]
   public string m_transactiontype;

   [XmlAttribute("TransactionTypeCode")]
   public string m_transactiontypecode;
}

我实例化和序列化如下;

   Transaction tx = new Transaction();

   tx.m_id = 1;   
   tx.m_transactiontype = "Withdrawal";  
   tx.m_transactiontypecode = "520";

   StringWriter o = new
   StringWriter(CultureInfo.InvariantCulture);
   XmlSerializer s = new
   XmlSerializer(typeof(Transaction));   
   s.Serialize(o, tx);   
   Console.Write(o.ToString());

给我:

   <Transaction TransactionTypeCode="520">
     <ID>1</ID>
     <TransactionType>Withdrawal</TransactionType> 
   </Transaction>

我想:

   <Transaction>
     <ID>1</ID>
     <TransactionType TransactionTypeCode="520">Withdrawal</TransactionType>
   </Transaction>

有人(Chris Dogget)建议:

   public class Transaction
   {

       [XmlElement("ID")]
       public int m_id;

       public TransactionType m_transactiontype;
   }

   public class TransactionType
   {
       public TransactionType(){}
       public TransactionType(string type) { this.m_transactiontype = type; }

       [XmlTextAttribute]
       public string m_transactiontype;

       [XmlAttribute("TransactionTypeCode")]
       public string m_transactiontypecode; 
   }

使用TransactionType类看起来很有希望 - 您能告诉我在序列化之前如何实例化类吗?

谢谢!

7 个答案:

答案 0 :(得分:2)

public class Transaction
{

    [XmlElement("ID")]
    public int m_id;

    public TransactionType type;
}

public class TransactionType
{
    public TransactionType(){}
    public TransactionType(string type) { this.@Type = type; }

    [XmlTextAttribute]
    public string @Type;

    [XmlAttribute("TypeCode")]
    public string typecode; 
}

给了我这个:

<?xml version="1.0" encoding="utf-16"?>
<Transaction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <ID>1</ID>
    <type TypeCode="520">Withdrawal</type>
</Transaction>

不幸的是,“Type”是.NET中的实际类型,所以你不能真正使用它(至少大写)作为你的字段名。

答案 1 :(得分:1)

我认为这样做的唯一方法是使用成员属性TypeCode创建一个Type类(不好名称,因为它也是框架中的关键字......)。然后,您将Type实例或引用作为类Transaction的一部分。

答案 2 :(得分:1)

假设您的类型代码为:

public class Transaction
{
    public Transaction() { ttype = new TransactionType(); }

    [XmlElement("ID")]
    public int id;

    [XmlElement("TransactionType")]
    public TransactionType ttype;
}

public class TransactionType
{
    public TransactionType(){}
    public TransactionType(string txType) { this.type = txType; }

    [XmlText]
    public string type;

    [XmlAttribute("TransactionTypeCode")]
    public string typecode;
}

此代码将按您希望的方式初始化和序列化:

public void Run()
{
    XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
    ns.Add( "", "" );

    Transaction tx = new Transaction();
    tx.id = 1;
    tx.ttype.type = "Withdrawal";
    tx.ttype.typecode = "520"; 
    using (StringWriter o = 
          new StringWriter(CultureInfo.InvariantCulture))
    {
        XmlSerializer s = new XmlSerializer(typeof(Transaction));
        s.Serialize(o, tx, ns);
        Console.Write(o.ToString());
    }
}

答案 3 :(得分:0)

我猜你应该用Type和TypeCode字段创建一个单独的类。 使用[XmlAttribute]装饰TypeCode,使用[XmlText]装饰。

答案 4 :(得分:0)

实施IXmlSerializable并使用Linq to XML to construct your serialized object

通过这种方式,您可以精确控制xml的外观。

就个人而言,我会放弃XmlSerialization,使用XAML并忘记尝试获取XML 外观。它可以看起来像垃圾,只要它有效!

答案 5 :(得分:0)

您所需的XML与您在代码中布置对象的方式不一致。

如果您阅读XML,则说明以下内容......

该事务包含两个元素:ID和Type。 Type有一个名为TypeCode

的属性

如果你看一下你想要创造的对象,你就是这样说的......

该事务包含三个属性:ID,Type和TypeCode

...你可以看到两者之间的脱节。你必须调整每个目标以获得正确的序列化(修改类或xml,以便两者对齐你要尝试通信的内容)。

答案 6 :(得分:0)

好的,我们删除“'type'是.NET中的一个类型”问题(我的不好):

   public class Transaction
   {
       [XmlElement("ID")]
       public int m_id;

       [XmlElement("TransactionType")]
       public string m_transactiontype;

       [XmlAttribute("TransactionTypeCode")]
       public string m_transactiontypecode;
   }

我实例化和序列化如下;

   Transaction tx = new Transaction();

   tx.m_id = 1;
   tx.m_transactiontype = "Withdrawal";
   tx.m_transactiontypecode = "520";

   StringWriter o = new StringWriter(CultureInfo.InvariantCulture);
   XmlSerializer s = new XmlSerializer(typeof(Transaction));
   s.Serialize(o, tx);
   Console.Write(o.ToString());

给我:

<Transaction TransactionTypeCode="520">
  <ID>1</ID>
  <TransactionType>Withdrawal</TransactionType>
</Transaction>

我想:

<Transaction>
  <ID>1</ID>
  <TransactionType TransactionTypeCode="520">Withdrawal</TransactionType>
</Transaction>

使用TransactionType类看起来很有希望 - 您能告诉我在序列化之前如何实例化类吗?

谢谢!