使用LINQ在XML中查询具有相同名称的嵌套元素

时间:2015-07-09 07:32:19

标签: c# xml linq

我有一个xml文件,我查询的内容如下:

<Product ID="Sample A" UserTypeID="TYPE_PRD_RANGE">
  <MultiValues>
  <Value>
   <Value AttributeId = "Att_1">Value1</Value>
  </>Values>
  <MultiValues>
  <Values AttributeId = "Att_2">
    <Value AttributeId = "Att_3">Value1</Value>
    <Value AttributeId = "Att_4">Value2</Value>
    <Value AttributeId = "Att_5">Value3</Value>
    <Value AttributeId = "Att_6">Value4</Value>
  </Values>
  <Product ID="Sample A_1" UserTypeID="SUB_RANGE">
    <Values AttributeId = "Att_2_5">
      <Value AttributeId = "Att_2_4">Value1</Value>
      <Value AttributeId = "Att_2_3">Value2</Value>
      <Value AttributeId = "Att_2_1">Value3</Value>
      <Value AttributeId = "Att_2_2">Value4</Value>
    </Values>
  </Product>
  <Product ID="Sample A_1_1" UserTypeID="ITEM">
    <Values AttributeId = "12345">
      <Value AttributeId = "Att_2_1_1">Value1</Value>
      <Value AttributeId = "Att_2_2_1">Value2</Value>
      <Value AttributeId = "Att_2_3_1">Value3</Value>
      <Value AttributeId = "Att_2_4_1">Value4</Value>
    </Values>
  </Product>    
</Product>

基本上我有我在每个产品中寻找的某些属性。我需要TYPE_PRD_RANGESUB_RANGEITEM中的属性,我想将它们全部嵌套在文本文件中。 目前,我分别查询所有三个元素并写入不同的txt文件,然后手动确定哪些TYPE_PRD_RANGE链接到SUB_RANGE链接到ITEM列表。但这很乏味,有些值没有正确输入系统,容易出现人为错误。

当前代码:

   var rangedesiredIds = new[]  {//attributes needed from range here};

   var subRangeDesiredIds = new[]{//attributes needed from subrange here};

   var itemDesiredIds = new[]{//attributes needed from items here};         


    //Export all the main product ranges from here..........
   var rangeProducts = xml.Descendants("Product")
   .Where(x => (string)x.Attribute("UserTypeID") ==TYPE_PRD_RANGE);
    var rangeproductDetails = rangeProducts.Select(x => new
        {
            ID = (String)x.Attribute("ID"), 
            UserTypeID = (String)x.Attribute("UserTypeID"), 
            Values = x.Descendants("Value")
                      .Where(y=>rangedesiredIds.Contains(y.Attribute("AttributeID"))),
          MultiValue = x.Descendants("MultiValue")
                       .Where(y => rangedesiredIds.Contains(y.Attribute("AttributeID")))}

                );

//Rinse and repeat for `SUB_RANGE` and `ITEM`

理想情况下,我希望以下文本格式输出:

"range_Product ID" ,"range_Attribute 1.Value", 
    "subrange Product_ID", "subrange_Attribute2.Value" 
        Item Product_ID,  "item_Attribute_1.Value" ,"item_Attribute_2.Value"
        Item Product_ID,  "item_Attribute_1.Value" ,"item_Attribute_2.Value"

任何帮助都表示赞赏。

1 个答案:

答案 0 :(得分:0)

使用字符串连接

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;


namespace ConsoleApplication34
{
    class Program
    {

        static void Main(string[] args)
        {
            string input =
                "<Root>" +
                "<Product ID=\"Sample A\" UserTypeID=\"TYPE_PRD_RANGE\">" +
                  "<MultiValues>" +
                  "<Values>" +
                   "<Value AttributeId = \"Att_1\">Value1</Value>" +
                  "</Values>" +
                  "</MultiValues>" +
                  "<Values AttributeId = \"Att_2\">" +
                    "<Value AttributeId = \"Att_3\">Value1</Value>" +
                    "<Value AttributeId = \"Att_4\">Value2</Value>" +
                    "<Value AttributeId = \"Att_5\">Value3</Value>" +
                    "<Value AttributeId = \"Att_6\">Value4</Value>" +
                  "</Values>" +
                  "<Product ID=\"Sample A_1\" UserTypeID=\"SUB_RANGE\">" +
                    "<Values AttributeId = \"Att_2_5\">" +
                      "<Value AttributeId = \"Att_2_4\">Value1</Value>" +
                      "<Value AttributeId = \"Att_2_3\">Value2</Value>" +
                      "<Value AttributeId = \"Att_2_1\">Value3</Value>" +
                      "<Value AttributeId = \"Att_2_2\">Value4</Value>" +
                    "</Values>" +
                  "</Product>" +
                  "<Product ID=\"Sample A_1_1\" UserTypeID=\"ITEM\">" +
                    "<Values AttributeId = \"12345\">" +
                      "<Value AttributeId = \"Att_2_1_1\">Value1</Value>" +
                      "<Value AttributeId = \"Att_2_2_1\">Value2</Value>" +
                      "<Value AttributeId = \"Att_2_3_1\">Value3</Value>" +
                      "<Value AttributeId = \"Att_2_4_1\">Value4</Value>" +
                    "</Values>" +
                  "</Product>" +
                "</Product>" +
                "</Root>";


            XElement products = XElement.Parse(input);

            var results = products.Elements("Product").Select(x => new
            {
                ID = x.Attribute("ID").Value,
                valueId = x.Descendants("Value").Attributes("AttributeId").FirstOrDefault().Value,
                products = x.Elements("Product").Select(y => new
                {
                    ID = y.Attribute("ID").Value,
                    Name = y.Attribute("UserTypeID").Value,
                    values = y.Element("Values").Elements("Value").Select(z => new
                    {
                        ID = z.Attribute("AttributeId").Value,
                        Value = (string)z
                    }).ToList()
                    .Select(aa =>  string.Join(",", new string[] { aa.ID, aa.Value })).ToList()
                }).ToList()
                .Select(ac => ac.values.Select(ad => string.Join(",", new string[] { ac.ID, ac.Name, ad }))).ToList()
            }).ToList()
            .Select(ae => ae.products.Select(af => af.Select(ag => string.Join(",", new string[] { ae.ID, ae.valueId, ag })).ToList()).ToList()).ToList();

        }

    }

}