C# 反序列化XML字符串无效

C# 反序列化XML字符串无效,c#,xml-serialization,xml-deserialization,C#,Xml Serialization,Xml Deserialization,我有这个XML字符串 <Root> <Row> <ITEMNO>1</ITEMNO> <PARTSOURCE>Buy</PARTSOURCE> <QTY>2</QTY> <CUSTPARTNO>469</CUSTPARTNO> <DESCRIPT>35W 1/4W 5%</DESCRIPT> </Ro

我有这个XML字符串

<Root>
  <Row>
    <ITEMNO>1</ITEMNO>
    <PARTSOURCE>Buy</PARTSOURCE>
    <QTY>2</QTY>
    <CUSTPARTNO>469</CUSTPARTNO>
    <DESCRIPT>35W 1/4W 5%</DESCRIPT>
  </Row>
  <Row>
    <ITEMNO>3</ITEMNO>
    <PARTSOURCE>Buy</PARTSOURCE>
    <QTY>5</QTY>
    <CUSTPARTNO>116</CUSTPARTNO>
    <DESCRIPT>1.74K 1/8W 1% Film</DESCRIPT>
  </Row>
  <Row>
    <ITEMNO>2</ITEMNO>
    <PARTSOURCE>MAKE</PARTSOURCE>
    <QTY>5</QTY>
    <CUSTPARTNO>651321</CUSTPARTNO>
    <DESCRIPT>Make Part</DESCRIPT>
  </Row>
</Root>
使用此方法:

public Root TransformXMLToClass(string pXml)
{
    var serializer = new XmlSerializer(typeof(Root));
    XmlReader reader = XmlReader.Create(new StringReader(pXml));

    return (Root)serializer.Deserialize(reader);
}
这仅适用于第一个节点

我尝试过像这样更改
类:

    public List<BOMItems> Row{get;set;}
public class Root
{
    [XmlElement("Row")]
    public BOMItems[] Row { get; set; }
}
公共列表行{get;set;}
它对任何节点都不起作用


如何使其反序列化所有节点?

您的BOM类应该如下所示

[XmlElement("ITEMNO")]
public string ITEMNO { get; set; }
以便通知序列化程序您已读取ITEMNO并将其保存在ITEMNO中

编辑: 必须为BOM类的每个属性执行此操作

答:(与名单一起)

公共类根目录
{
[XmlElement(“行”)]
公共列表行{get;set;}
}
公营银行
{
[XmlElement(“项目编号”)]
公共字符串ITEMNO{get;set;}
[XmlElement(“已使用”)]
使用的公共字符串{get;set;}
[XmlElement(“PARTSOURCE”)]
公共字符串PARTSOURCE{get;set;}
[XmlElement(“数量”)]
公共字符串数量{get;set;}
[XmlElement(“CUSTPARTNO”)]
公共字符串CUSTPARTNO{get;set;}
[XmlElement(“CREV”)]
公共字符串CREV{get;set;}
[XmlElement(“描述符”)]
公共字符串描述符{get;set;}
}
班级计划
{
静态void Main(字符串[]参数)
{
var serializer=新的XmlSerializer(typeof(Root));
var reader=XmlReader.Create(新的StringReader(File.ReadAllText(“c:\\tet.xml”));
var serializedOutput=(根)序列化程序。反序列化(读取器);
Console.ReadKey();
}

您的BOM类应该如下所示

[XmlElement("ITEMNO")]
public string ITEMNO { get; set; }
以便通知序列化程序您已读取ITEMNO并将其保存在ITEMNO中

编辑: 必须为BOM类的每个属性执行此操作

答:(与名单一起)

公共类根目录
{
[XmlElement(“行”)]
公共列表行{get;set;}
}
公营银行
{
[XmlElement(“项目编号”)]
公共字符串ITEMNO{get;set;}
[XmlElement(“已使用”)]
使用的公共字符串{get;set;}
[XmlElement(“PARTSOURCE”)]
公共字符串PARTSOURCE{get;set;}
[XmlElement(“数量”)]
公共字符串数量{get;set;}
[XmlElement(“CUSTPARTNO”)]
公共字符串CUSTPARTNO{get;set;}
[XmlElement(“CREV”)]
公共字符串CREV{get;set;}
[XmlElement(“描述符”)]
公共字符串描述符{get;set;}
}
班级计划
{
静态void Main(字符串[]参数)
{
var serializer=新的XmlSerializer(typeof(Root));
var reader=XmlReader.Create(新的StringReader(File.ReadAllText(“c:\\tet.xml”));
var serializedOutput=(根)序列化程序。反序列化(读取器);
Console.ReadKey();
}

在您的例子中,它非常简单。您只需要告诉序列化程序如何处理元素集合

您确实需要将属性作为集合或数组,如下所示:

    public List<BOMItems> Row{get;set;}
public class Root
{
    [XmlElement("Row")]
    public BOMItems[] Row { get; set; }
}
“[XmlElement]”将告诉序列化程序如何正确反序列化。添加XmlElementAttribute将告诉序列化程序将其视为“平面”序列

<!-- Row Elements Flattened -->
<Root>
  <Row>
    <ITEMNO>1</ITEMNO>
    <PARTSOURCE>Buy</PARTSOURCE>
    <QTY>2</QTY>
    <CUSTPARTNO>469</CUSTPARTNO>
    <DESCRIPT>35W 1/4W 5%</DESCRIPT>
  </Row>
  <Row>
    <ITEMNO>3</ITEMNO>
    <PARTSOURCE>Buy</PARTSOURCE>
    <QTY>5</QTY>
    <CUSTPARTNO>116</CUSTPARTNO>
    <DESCRIPT>1.74K 1/8W 1% Film</DESCRIPT>
  </Row>
</Root>

    <!-- Versus Row Elements Unflattened -->
<Root>
  <Row>
    <BOMItems>
      <ITEMNO>1</ITEMNO>
      <PARTSOURCE>Buy</PARTSOURCE>
      <QTY>2</QTY>
      <CUSTPARTNO>469</CUSTPARTNO>
      <DESCRIPT>35W 1/4W 5%</DESCRIPT>
    </BOMItems>
    <BOMItems>
      <ITEMNO>3</ITEMNO>
      <PARTSOURCE>Buy</PARTSOURCE>
      <QTY>5</QTY>
      <CUSTPARTNO>116</CUSTPARTNO>
      <DESCRIPT>1.74K 1/8W 1% Film</DESCRIPT>
    </BOMItems>
  </Row>
</Root>

1.
购买
2.
469
35瓦1/4瓦5%
3.
购买
5.
116
1.74K 1/8W 1%胶片
1.
购买
2.
469
35瓦1/4瓦5%
3.
购买
5.
116
1.74K 1/8W 1%胶片

在您的例子中,它非常简单。您只需要告诉序列化程序如何处理元素集合

您确实需要将属性作为集合或数组,如下所示:

    public List<BOMItems> Row{get;set;}
public class Root
{
    [XmlElement("Row")]
    public BOMItems[] Row { get; set; }
}
“[XmlElement]”将告诉序列化程序如何正确反序列化。添加XmlElementAttribute将告诉序列化程序将其视为“平面”序列

<!-- Row Elements Flattened -->
<Root>
  <Row>
    <ITEMNO>1</ITEMNO>
    <PARTSOURCE>Buy</PARTSOURCE>
    <QTY>2</QTY>
    <CUSTPARTNO>469</CUSTPARTNO>
    <DESCRIPT>35W 1/4W 5%</DESCRIPT>
  </Row>
  <Row>
    <ITEMNO>3</ITEMNO>
    <PARTSOURCE>Buy</PARTSOURCE>
    <QTY>5</QTY>
    <CUSTPARTNO>116</CUSTPARTNO>
    <DESCRIPT>1.74K 1/8W 1% Film</DESCRIPT>
  </Row>
</Root>

    <!-- Versus Row Elements Unflattened -->
<Root>
  <Row>
    <BOMItems>
      <ITEMNO>1</ITEMNO>
      <PARTSOURCE>Buy</PARTSOURCE>
      <QTY>2</QTY>
      <CUSTPARTNO>469</CUSTPARTNO>
      <DESCRIPT>35W 1/4W 5%</DESCRIPT>
    </BOMItems>
    <BOMItems>
      <ITEMNO>3</ITEMNO>
      <PARTSOURCE>Buy</PARTSOURCE>
      <QTY>5</QTY>
      <CUSTPARTNO>116</CUSTPARTNO>
      <DESCRIPT>1.74K 1/8W 1% Film</DESCRIPT>
    </BOMItems>
  </Row>
</Root>

1.
购买
2.
469
35瓦1/4瓦5%
3.
购买
5.
116
1.74K 1/8W 1%胶片
1.
购买
2.
469
35瓦1/4瓦5%
3.
购买
5.
116
1.74K 1/8W 1%胶片


您应该在序列化过程中添加“XmlElement”在序列化过程中..使用[XmlElement]装饰BOM类中的属性嗯?你能提供更多的细节吗?在哪里?看到下面关于序列化的答案在旁注上,你可以尝试将XDoc与最新版本的dot netIt一起使用。根据我的描述,它仍然只获得第一个节点,我在添加装饰之前就这样做了。我会尝试。不相关的,你的建议确实解决了我的另一个问题,但到目前为止,还没有解决我的问题n关注点。就像前面列表阻止它加载第一个节点一样。实际上,如果您执行如下操作:[XmlElement]公共列表行{get;set;},它将工作已经尝试过了,结果没有什么不同。它必须是一个数组。根据我的描述,它仍然只得到第一个节点,我在添加装饰之前做过。我会尝试。不相关的,你的建议确实解决了我遇到的另一个问题,但到目前为止,不是我主要关心的问题。正如之前的列表阻止它加载第一个节点。Ac实际上,如果您执行如下操作:[XmlElement]public List Row{get;set;},它将起作用已经尝试过了,结果没有什么不同。它必须是ArrayTanks!我想我以前也尝试过。可能是因为我没有先装饰它。很高兴我能提供帮助。序列化程序非常有用,但有时需要一些工作才能使类与输入匹配。请查看有关使用属性t的有用信息o控制它。@Xenophile:答案很好。但是,对行使用[XmlElement]有效,但我尝试给[XmlElement(“根”)]无效。有什么想法吗?@now:我不确定我是否理解这个问题。将[XmlElement]应用于数组或列表将使其平坦,以便数组中的每个项都是它自己的标记。这是[XmlElement]的另一种用法它消除了序列化程序通常查找的容器标记