使用LINQ从XML

时间:2015-05-06 11:34:27

标签: c# xml linq

我有一个XML文件,我试图从中提取一些信息。该文件包含产品及其属性列表。我试图为Tekla创建3D模型,因此只有部分属性与我相关。 我之前的实习生是手动完成的。我的问题是有10个文件,每个文件超过100MB。我没有兴趣浪费我存在的大部分内容来筛选超过100万行代码。这是Xml文件中每个Product条目的基本设置。

  <Product ID="productID" UserTypeID="USERTYPE">
    <Name>PRODUCT NAME</Name>
      <ClassificationReference ClassificationID=" CLASSIFICATION_PARKING"  Type="LINK_TYPE_CLASSIFICATION_SYSTEM"/>

    <Values>
      <Value AttributeID="CHA_STREETPRICE_STD_NETAMOUNT">0.00</Value>
      <Value AttributeID="CHA_SAP_MATMAS_WERKS">0000</Value>
      <Value AttributeID="CHA_STREETPRICE_STD_CURRENCY">EUR</Value>
      <Value AttributeID="CHA_SAP_MATMAS_ZZPUBLISH">00000</Value>
      <Value AttributeID="CHA_SAP_MATMAS_ZZCATALOG_TYPE">00000</Value>
      <Value AttributeID="CHA_SAP_MATMAS_MARM_PCE_MEINH">0000</Value>
      <Value AttributeID="CHA_STREETPRICE_STD_QUANTITY">1</Value>
      <Value AttributeID="CHA_SAP_MATMAS_MARM_PCE_UMREZ">1</Value>
      <Value AttributeID="CHA_SAP_MATMAS_ZZDISCGRP">000000</Value>
      <Value AttributeID="CHA_STREETPRICE_STD_NETPRICE">0.00</Value> 
    </Values>
  </Product>

我刚刚发现了LINQ,但我认为它可以在这里帮助我。我的问题是我似乎只知道LINQ和XML的基础知识。我脑子里有一个基本的方法,但我不太清楚如何编写查询。 这就是我的想法:

我只需要某些USERTYPE的产品,因此我会忽略所有产品元素USERTYPE

然后我想提取产品属性&#34; ID&#34;和&#34; USERTYPE&#34;与Name节点一起使用。

然后根据Values提取attributeID节点中的值。我不想要所有属性。

在一行上写入文本文件。 但是,我在第一步遇到了绊脚石。我收到了这个问题:

// find Products with USERTYPE "PRD"    

  static IEnumerable<string>GetKeyWordNames(string file)
            {
                return XDocument.Load(file)
                    .Descendants("Product")
                    .Attributes("ID")      // how do you write a query to select multiple attributes
                    .Select(attr => attr.Value)
                    .ToList();
            }  

这是我想要实现的目标:

if(Attributes[0] == "ID"&& Attributes[1].Value = "thisValue")
select(product);  

不幸的是,我不太确定如何使用LINQ实现这一目标。 所以我的问题很简单:

如何查询多个属性,仅根据属性类型选择产品?

如何根据Values查询AttributeID个节点。 ValuesProduct的后代还是内部节点?

我如何存储所述结果。

2 个答案:

答案 0 :(得分:1)

据我了解你的问题,这就是你想要的(除了值中的AttributeId属性): -

  

我只需要某些USERTYPE的产品,所以我会忽略所有产品   没有USERTYPE的元素

您需要过滤数据,因此需要.Where方法。

在此之后我们所做的就是投射产品节点中存在的元素。

List<Product> result = xdoc.Descendants("Product")
                           .Where(x => (string)x.Attribute("UserTypeID") == "1")
                           .Select(x => new Product
                           {
                              ProductId = (string)x.Attribute("ID"),
                              UserTypeID = (string)x.Attribute("UserTypeID"),
                              ProductName = (string)x.Element("Name"),
                              ValuesIds = x.Descendants("Value")
                                         .Select(z => (string)z.Attribute("AttributeID"))
                                         .ToList()
                           }).ToList();

这里我认为生成的Product类型是这样的: -

public class Product
    {
        public string ProductId { get; set; }
        public string UserTypeID { get; set; }
        public string ProductName { get; set; }
        public List<string> ValuesIds { get; set; }
    }
  

我不希望所有属性只是一些。

您尚未指定要在AttributeID节点中获取Values属性的基础,这就是我全部获取它们的原因。

答案 1 :(得分:0)

我这里没有Visual Studio尝试,但我认为你可以使用Where来实现你想要的目标。

XDocument.Load(file)
         .Descendants("Product")
         .Where(element => element.Attribute("ID") != null && element.Attribute("ID").Value == "thisValue")
         .ToList();

它将返回具有指定ID属性的“Product”节点列表。 不知道它是否有效,但是类似的东西。