2

我有以下 xml 格式

<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>

我一直在尝试将其放入一个如下所示的数据表中

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 实现这一点?

4

1 回答 1

6

那里的代码中有很多事情发生,其中大部分都不好。您只是没有正确使用 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
    );
}
于 2013-03-04T00:25:28.930 回答