C#序列化 移除结果中的属性名称

3

我无法从我的xml中删除clsProduct中属性名称为Values的名称。 我尝试为我的List<clsValues>使用[XmlElement(ElementName = "Values", Type = typeof(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>

Result I need:

<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>

1
顺便提一下,现在是停止使用 cls 前缀并开始遵循正常的 .NET 命名约定的绝佳时机。 - Jon Skeet
@JonSkeet 我通常不使用前缀。我正在扩展项目,而不想在一个应用程序中有两种命名约定。 - remarkies
我建议你的同事们开始遵循命名规范,而且不要忘记你正在发布一个 Stack Overflow 的问题;只要它展示了完全相同的问题,它并不需要是精确的代码。这意味着你可以让它更简单、更常规化,以提供更少的干扰给读者。 - Jon Skeet
4个回答

2

您的问题与此属性相关:

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

暗示存在多个名为Values的元素,这些元素具有特定类型clsValues。每一个元素都有一个或两个子元素ValueMultiValue
您需要的是将数组作为一个元素Values,并使数组项成为两种不同元素类型之间的选择 - 它可能包含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; }
}

请查看此代码片段以查看可运行的演示。


1
也许你应该使用:
[XmlElement(ElementName = "Values", Type = typeof(clsValues))]
public List<clsValues> Values { get; set; }

相反

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

当我实现时,第一个和最后一个<Values>会消失。 - remarkies

0

尝试使用 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());
            }
        }
    }
}

0

为什么序列化会这样,是因为XML使用第二个<Values></Values>作为分隔符。这是必要的,因为您的clsValues对象可以同时设置ValueMultiValue属性。在这种情况下,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>

可以被反向解释为设置了Value的1个对象和设置了ValueMultiValue的1个对象,这是错误的;或者被解释为设置了Value的1个对象、设置了Value的1个对象和设置了MultiValue的1个对象,这是正确的。但XML解析器无法知道哪种解释是正确的。如果您确定您的对象始终只具有1个已设置的属性,则可以编写自己的序列化程序和反序列化程序,并实现一种属性规则。


据我理解您的帖子,序列化程序无法将XML序列化为我所需的格式? - remarkies

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接