1

我正在尝试使用 Linq 将 XML 字符串转换为 .net 对象的常规集合(我讨厌 linq ......主要是因为我没有时间准确地了解它是如何工作的,因此,当事情发生时,我总是很困惑出错)。我希望有一种使用 XSD 之类的简单易用的方法,以及某种反序列化器和再序列化器……但.net 中似乎没有任何本机支持。所以我想,为什么不直接使用 Linq?大错。但无论如何,我想把这个字符串...

<?xml version="1.0" encoding="utf-16"?>
  <ArrayOfPopulation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Population>
  <id>3</id>
  <name>CHF</name>
  <description>FR Congestive Heart Failure</description>
  <createdDate>2011-10-25T04:00:00Z</createdDate>
  <createdUserID>WPS_ANEMIA_POP_OWNER</createdUserID>
  <modifiedDate>2011-10-31T04:00:00Z</modifiedDate>
  <modifiedUserID>WPS_ANEMIA_POP_OWNER</modifiedUserID>
  <isActive>true</isActive>
  <owner>
    <type>AD GROUP</type>
  </owner>   
  <owner>
    <type>ACCOUNT</type>
  </owner>
  <type>
    <name>ACO SURVEY</name>
  </type>
  </Population>
  <Population>
  <id>2</id>
  <name>COPD</name>
  <description>FR Chronic Obstructive Pulmonary Disease</description>
  <createdDate>2011-10-25T04:00:00Z</createdDate>
  <createdUserID>WPS_ANEMIA_POP_OWNER</createdUserID>
  <modifiedDate>2011-10-31T04:00:00Z</modifiedDate>
  <modifiedUserID>WPS_ANEMIA_POP_OWNER</modifiedUserID>
  <isActive>true</isActive>
  <owner>
    <domain>1UPMC-ACCT</domain>
    <name>InteropDev</name>
    <type>AD GROUP</type>
  </owner>
  <owner>
    <domain>1UPMC-ACCT</domain>
    <name>ACOPopulationUsers</name>
    <type>AD GROUP</type>
  </owner>
  <owner>
    <domain>1UPMC-ACCT</domain>
    <name>muesml</name>
    <type>ACCOUNT</type>
  </owner>
  <owner>
    <domain>1UPMC-ACCT</domain>
    <name>andersonjm</name>
    <type>ACCOUNT</type>
  </owner>
  <type>
    <name>ACO SURVEY</name>
  </type>
 </Population>
 </ArrayOfPopulation>

进入这些对象的数组...

public class PopulationModel
{
    public string populationID { set; get; }

    public string PopName { set; get; }

    public string Description { set; get; }

    public int PopulationType { set; get; }

    public int isActive { set; get; }

    //public List<XSLTACOData> patients { set; get; }
}

哪个看起来像这样......

public class PopulationsModel
{
    public List<PopulationModel> Populations { set; get; }
}

我没有使用这个 linq to XML 查询来做到这一点......

XDocument xDocument = XDocument.Parse(xmlFromSvc);
XElement elem = xDocument.Element("ArrayOfPopulation");
//client.GetOwnedPopulations();
IEnumerable<PopulationsModel> popModel = (IEnumerable<PopulationsModel>)
     (from templates in elem.Elements("Population")
      select new PopulationModel
      {
          populationID = templates.Attribute("id").Value,
          PopName = templates.Attribute("name").Value,
          Description = templates.Attribute("description").Value,
          PopulationType = int.Parse(templates.Attribute("").Value),
          isActive = int.Parse(templates.Attribute("isActive").Value)
      }).ToList();

我正式感到困惑。为什么这不起作用?此外,必须有一种更简单的方法来完成这项工作吗?对于 xsd 和所有其他垃圾来说,这似乎是完美的选择。也许我在这里努力工作?

现在得到这个例外......

Unable to cast object of type  'System.Collections.Generic.List`1[FocusedReadMissionsRedux.Models.PopulationModel]' to type 'System.Collections.Generic.IEnumerable`1[FocusedReadMissionsRedux.Models.PopulationsModel]'.

这似乎是一个稍微合理的例外。

4

2 回答 2

4

为什么这不起作用?

好吧,让我们看看你在做什么。你有templates一个<Population>元素,然后你像这样查询它:

  populationID = templates.Attribute("id").Value,
  PopName = templates.Attribute("name").Value,
  Description = templates.Attribute("description").Value,
  PopulationType = int.Parse(templates.Attribute("").Value),
  isActive = int.Parse(templates.Attribute("isActive").Value)

请注意您如何在Attribute此处使用所有内容。现在查看 XML:

<Population>
  <id>3</id>
  <name>CHF</name>
  ...
</Population>

Population元素没有任何属性。它有嵌套元素。我没有详细检查,但是将所有Attribute调用更改为Element调用可能会解决所有问题,除了PopulationType. (不清楚你想从哪里得到它。)

请注意,从XAttributeand的显式转换XElement通常比int.Parseetc更干净。

于 2012-05-21T19:02:45.750 回答
2

Attribute当它们实际上是元素时,您正在尝试使用方法获得价值。

试试这个(老实说我没有测试过):

XDocument xDocument = XDocument.Parse(xmlFromSvc);
XElement elem = xDocument.Element("ArrayOfPopulation");

var popModel = (from templates in elem.Elements("Population")
                select new PopulationModel
                {
                     populationID = (string)templates.Element("id"),
                     PopName = (string)templates.Element("name"),
                     Description = (string)templates.Element("description"),
                     PopulationType = (int)templates.Element("Type").Element("Name"),
                     isActive = (int)templates.Element("isActive")
                }).ToList();
于 2012-05-21T19:03:23.613 回答