2015-05-06 3 views
2

У меня есть XML-файл, и я пытаюсь извлечь некоторую информацию из файла. Список содержит список продуктов и их атрибутов. Я пытаюсь создать 3D-модели для Tekla, поэтому только некоторые из этих атрибутов имеют отношение ко мне. Стажер передо мной делал это вручную. Моя проблема в том, что есть 10 файлов, и каждый файл имеет размер более 100 МБ. Я не заинтересован в том, чтобы тратить значительную часть моего существования, просеивая более 1 миллиона строк кода. Вот базовая настройка каждой записи продукта в файле Xml.Использование LINQ для извлечения атрибутов из XML

<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. У меня есть базовый подход в моей голове, но я не совсем уверен, как писать запросы. Вот что я имею в виду:

I только нуждаются продукты определенного USERTYPE, так что я бы игнорировать все элементы продукта без этого USERTYPE

Тогда я хотел бы, чтобы извлечь атрибуты продукта «ID» и «UserType »вместе с узлом 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. Является Values потомком Product или innerNode?

Как сохранить указанные результаты.

ответ

1

Насколько я понял ваш вопрос, это то, что вы хотите (кроме AttributeId атрибут присутствует в Values): -

мне нужно только продукты определенного 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 узле, поэтому я подгружать их всех.

+0

Что делать, если я должен был получить два атрибута из приведенного выше кода: «ValuesIds = x.Descendants (« Значение »). Где (z => (строка) z.Attribute (« AttributeID ») ==« CHA_SAP_MATMAS_ZZCATALOG_TYPE ») .Выберите (z => (string) z.Attribute ("AttributeID")) .ToList() 'Могу ли я создать массив атрибутов и передать его в LINQ следующим образом:' ValuesIds = x.Descendants ("Value "). Где (z => (строка) z.Attribute (" AttributeID ") == wantedIDs)' –

+0

Ничего. Решил. –

+0

@MaskedAfrican - Рад, что это помогло вам, и вы решили другую часть самостоятельно :) –

0

У меня нет Visual Studio здесь, чтобы попробовать, но я думаю, вы можете использовать Where для достижения того, чего хотите.

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

Он вернет список узлов «Product» с указанным атрибутом ID. Не знаю, работает ли это, но что-то в этом роде.

Смежные вопросы