2013-03-03 3 views
2

я имею следующий XMLLINQ к XML в DataTable

появляются две
<feed> 
<entry> 
    <s:product> 
    <s:author> 
    <s:name>amazone</s:name> 
    <s:accountId>1111</s:accountId> 
    </s:author> 
    <s:title>xxx 
    </s:title> 
    <s:condition>used 
    </s:condition> 
    <s:inventories> 
    <s:inventory channel="online" availability="inStock"> 
    <s:price shipping="4.9" currency="EUR">14.95</s:price> 
    </s:inventory> 
    </s:inventories> 
    </s:product> 
</entry> 
<entry> 
    <s:product> 
    <s:author> 
    <s:name>ebay</s:name> 
    <s:accountId>1221</s:accountId> 
    </s:author> 
    <s:title>yyy 
    </s:title> 
    <s:condition>new 
    </s:condition> 
    <s:inventories> 
    <s:inventory channel="online" availability="inStock"> 
    <s:price shipping="4.90" currency="EUR">99.95</s:price> 
    </s:inventory> 
    </s:inventories> 
    </s:product> 
</entry> 
</feed> 

я пытался поставить его в DataTable, который будет выглядеть следующим

name  condition  price  shipping  totalprice  availablity 
amazone used   14.95  4.95   19.90   inStock 
ebay  new    99.95  4.90   104.85   inStock 

как вы можете видеть каждый <entry> должен быть строкой, и я не хочу, значения всех тегов, только следующее

column name  :value of <s:name>  
column condition :value of <s:condition> 
column sprice  :value of <s:price> 
column shipping :value of shipping which is an attribute of <s:price> 
column totalprice :value of <s:price> + its attribute shipping 
column avilability:value of avialability an attribute of <s:inventory> 

хау могу ли я достичь этого с помощью LINQ?

ответ

5

В вашем коде есть много вещей, большинство из которых не очень хорошо. Вы просто не используете библиотеку LINQ to XML правильно.

  • Ваш XML-документ и данные, которые вас интересуют, имеют пространства имен. Вы отказались от декларации пространства имен в документе и не получили доступ к каким-либо элементам должным образом.

    Вам необходимо создать переменную переменной XNamespace в пространство имен, используемое в документе, и использовать ее при попытке ссылки на соответствующие элементы.

  • Вы не можете просто передать значение элемента/атрибута (строки) в double, как это, вам придется проанализировать его в этом случае. Однако LINQ to XMl предоставляет явные приведения, которые обрабатывают преобразования. Таким образом, вы применяете соответствующий тип к самому элементу/атрибуту, а не к содержанию, которое они содержат. Используйте это вместо управления Value.

    На стороне примечания, всякий раз, когда вы имеете дело с валютой, никогда не используйте double (или любой другой тип с плавающей точкой), используйте decimal.

  • Вы не можете создавать экземпляры строк данных, не создавая их из таблицы данных. Желательно, чтобы ваши запросы сначала касались данных. Создание новых строк данных для таблицы. После того, как у вас есть данные, будьте обеспокоены созданием строк и заполнением данных.

С учетом сказанного, вот как вы будете использовать его более правильно.

XDocument doc = GetDocument(); 
// assuming this is the correct namespace 
XNamespace s = "http://www.google.com/shopping/api/schemas/2010"; 
var query = 
    from product in doc.Root.Elements("entry").Elements(s + "product") 
    // declare some variables to make the query cleaner 
    let inventory = product.Element(s + "inventories").Element(s + "inventory") 
    let price = (decimal)inventory.Element(s + "price") 
    let shipping = (decimal)inventory.Element(s + "price").Attribute("shipping") 
    select new 
    { 
     Name = (string)product.Element(s + "author").Element(s + "name"), 
     Condition = (string)product.Element(s + "condition"), 
     Price = price, 
     Shipping = shipping, 
     TotalPrice = price + shipping, 
     Availability = (string)inventory.Attribute("availability"), 
    }; 

var dt = new DataTable(); 
dt.Columns.Add("Name", typeof(string)); 
dt.Columns.Add("Condition", typeof(string)); 
dt.Columns.Add("Price", typeof(decimal)); 
dt.Columns.Add("Shipping", typeof(decimal)); 
dt.Columns.Add("TotalPrice", typeof(decimal)); 
dt.Columns.Add("Availability", typeof(string)); 
foreach (var product in query) 
{ 
    dt.Rows.Add(
     product.Name, 
     product.Condition, 
     product.Price, 
     product.Shipping, 
     product.TotalPrice, 
     product.Availability 
    ); 
} 
+0

Я хочу, чтобы я мог дать вам +10 действительно. – user1590636