【问题标题】:C# Serialization Remove attribute name from resultC#序列化从结果中删除属性名称
【发布时间】:2016-07-28 06:39:22
【问题描述】:

我无法从我的 xml 中删除 clsProduct 中的属性 Values 的名称。我尝试将[XmlElement(ElementName = "Values", Type = typeof(clsValues)] 用于我的List<clsValues>,但它没有给我所需的结果。

你可以在下面看到我需要的结果。

我的序列化类的部分内容:

[Serializable]
public class clsProduct
{
    [XmlAttribute("ID")]
    public string ID { get; set; }

    [XmlAttribute("UserTypeID")]
    public string UserTypeID { get; set; }

    [XmlArrayItem(ElementName = "Values", Type = typeof(clsValues))]
    public List<clsValues> Values { get; set; }

}

[Serializable]
public class clsValues
{
    [XmlElement(ElementName = "Value")]
    public clsValue Value { get; set; }

    [XmlArray(ElementName = "MultiValue"),
    XmlArrayItem(ElementName = "Value")]
    public List<clsValue> MultiValue { get; set; }
}

[Serializable]
public class clsValue
{
    [XmlAttribute("AttributeID")]
    public string AttributeID { get; set; }

    [XmlText]
    public string Value { get; set; }
}

我当前的 xml 结果:

<Product ID="PROD-01111010" UserTypeID="Product">
   <Values>
     <Values>
        <Value AttributeID="ATTR-7196">201607280755</Value>
     </Values>
     <Values>
        <Value AttributeID="ATTR-6236">PTFE 125 + 25% GF, Platte</Value>
     </Values>
     <Values>
        <MultiValue>
            <Value>PLATTE</Value>
            <Value>LUBRIFLON 225</Value>
            <Value>PLAQUE</Value>
            <Value>LUBRIFLON 22</Value>
        </MultiValue>
     </Values>
  </Values>
</Product>

我需要的结果:

<Product ID="PROD-01111010" UserTypeID="Product">
  <Values>
     <Value AttributeID="ATTR-7196">201607280755</Value>
     <Value AttributeID="ATTR-6236">PTFE 125 + 25% GF, Platte</Value>
     <MultiValue>
        <Value>PLATTE</Value>
        <Value>LUBRIFLON 225</Value>
        <Value>PLAQUE</Value>
        <Value>LUBRIFLON 22</Value>
     </MultiValue>
   </Values>
 </Product>

有人可以帮忙吗?

谢谢

编辑: 当我使用时

[XmlElement(ElementName = "Values", Type = typeof(clsValues))] public List<clsValues> Values { get; set; }

而不是XmlArrayItem 我得到这个结果:

<Product ID="PROD-01111010" UserTypeID="Product">
     <Values>
        <Value AttributeID="ATTR-7196">201607280755</Value>
     </Values>
     <Values>
        <Value AttributeID="ATTR-6236">PTFE 125 + 25% GF, Platte</Value>
     </Values>
     <Values>
        <MultiValue>
            <Value>PLATTE</Value>
            <Value>LUBRIFLON 225</Value>
            <Value>PLAQUE</Value>
            <Value>LUBRIFLON 22</Value>
        </MultiValue>
     </Values>
</Product>

【问题讨论】:

  • 附带说明,现在是停止使用 cls 前缀并开始遵循正常 .NET 命名约定的好时机。
  • @JonSkeet 我通常不使用前缀。我没有创建我正在扩展它的项目,并且不希望在一个应用程序中有两种命名约定。
  • 好吧,我建议你的同事们开始遵循命名约定——不要忘记你正在发布一个 Stack Overflow 问题;它不必是确切的代码,只要它显示相同的确切问题即可。这意味着您可以使其更简单、更传统,从而减少对读者的干扰。

标签: c# xml xml-serialization removeclass


【解决方案1】:

您的问题与此属性有关:

[XmlArrayItem(ElementName = "Values", Type = typeof(clsValues))]
public List<clsValues> Values { get; set; }

这意味着有 多个 元素称为 Values,它们具有特定类型 clsValues。每一个都有Value 或MultiValue 中的一个或两个子级。

您想要的是 array 成为元素 Values 并且 array items 成为两种不同元素类型之间的选择 - 它要么包含Value 元素或 MultiValue 元素。

你可以这样构造来实现:

public class Product
{
    [XmlAttribute("ID")]
    public string Id { get; set; }

    [XmlAttribute("UserTypeID")]
    public string UserTypeId { get; set; }

    [XmlArray("Values")]
    [XmlArrayItem("Value", typeof(Value))]
    [XmlArrayItem("MultiValue", typeof(MultiValue))]
    public List<object> Values { get; set; }
}

public class MultiValue
{
    [XmlElement(ElementName = "Value")]
    public List<Value> Values { get; set; }
}

public class Value
{
    [XmlAttribute("AttributeID")]
    public string AttributeId { get; set; }

    [XmlText]
    public string Text { get; set; }
}

请参阅this fiddle 以获得工作演示。

【讨论】:

    【解决方案2】:

    也许你应该使用

    [XmlElement(ElementName = "Values", Type = typeof(clsValues))]
    public List<clsValues> Values { get; set; }
    

    代替

    [XmlArrayItem(ElementName = "Values", Type = typeof(clsValues))]
    

    【讨论】:

    • 当我实现第一个和最后一个 消失时。
    【解决方案3】:

    试试 xml linq

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Linq;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            const string FILENAME = @"c:\temp\test.xml";
            static void Main(string[] args)
            {
                XDocument doc = XDocument.Load(FILENAME);
    
                XElement values = doc.Descendants("Values").FirstOrDefault();
                List<XElement> elements = values.Elements().ToList();
                for (int index = elements.Count() - 1; index >= 0; index--)
                {
                    elements[index].ReplaceWith(elements[index].Elements());
                }
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      之所以这样序列化,是因为 XML 使用第二个 &lt;Values&gt;&lt;/Values&gt; 作为分隔符。这是必需的,因为您的clsValues 对象可以同时设置Value 和MultiValue 属性。在这种情况下,您需要的 XML 格式

      <Product ID="PROD-01111010" UserTypeID="Product">
        <Values>
           <Value AttributeID="ATTR-7196">201607280755</Value>
           <Value AttributeID="ATTR-6236">PTFE 125 + 25% GF, Platte</Value>
           <MultiValue>
              <Value>PLATTE</Value>
              <Value>LUBRIFLON 225</Value>
              <Value>PLAQUE</Value>
              <Value>LUBRIFLON 22</Value>
           </MultiValue>
         </Values>
       </Product>
      

      可能被向后解释为 1 个带有 Value 设置的对象和 1 个带有 Value 和 MultiValue 设置的对象,这是错误的,或者作为 1 个带有 Value 设置的对象,1 个带有 Value 设置的对象和1 个带有MultiValue 设置的对象是正确的。但是 XML 解析器无法知道,哪种解释是正确的。如果您确定您的对象将始终只有 1 个属性集,您可以编写自己的 Serializator 和 Deserializator 并实现一个属性规则。

      【讨论】:

      • 据我了解您的帖子,序列化程序无法以我需要的格式序列化 xml?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-28
      • 2020-12-26
      • 1970-01-01
      • 1970-01-01
      • 2016-01-14
      相关资源
      最近更新 更多