在不知道DOM

时间:2016-09-20 23:15:22

标签: c# linq-to-xml flatten

示例XML:

<Pricing>
  <PriceGuide id="e4c3db5c">
    <Name>Price Guide A</Name>
    <Products>
      <Product id="1">
        <Name>Product 1</Name>
        <Prices>
          <Price>
            <Region id="40">Chicago</Region>
            <PriceLow>48</PriceLow>
            <PriceHigh>52</PriceHigh>
            <UnitOfMeasure>MT</UnitOfMeasure>
          </Price>
          <Price>
            <Region id="71">Dallas</Region>
            <PriceLow>45.5</PriceLow>
            <PriceHigh>47</PriceHigh>
            <UnitOfMeasure>MT</UnitOfMeasure>
          </Price>
        </Prices>
      </Product>
      <Product id="2">
        <Name>Product 2</Name>
        <Prices>
          <Price>
            <Region id="40">Chicago</Region>
            <PriceLow>48</PriceLow>
            <PriceHigh>49</PriceHigh>
            <UnitOfMeasure>MT</UnitOfMeasure>
          </Price>
          <Price>
            <Region id="101">Los Angeles </Region>
            <PriceLow>43</PriceLow>
            <PriceHigh>45</PriceHigh>
            <UnitOfMeasure>MT</UnitOfMeasure>
          </Price>
          <Price>
            <Region id="71">Dallas</Region>
            <PriceLow>45.5</PriceLow>
            <PriceHigh>48.5</PriceHigh>
            <UnitOfMeasure>MT</UnitOfMeasure>
          </Price>
        </Prices>
      </Product>
    </Products>
  </PriceGuide>
</Pricing>



预期结果:(写入CSV文件或转储到DataTable中的数据)

Price Guide A, Product 1, Chicago, 48, 52, MT
Price Guide A, Product 1, Dallas, 45.5, 47, MT
Price Guide A, Product 2, Chicago, 48, 49, MT
Price Guide A, Product 2, Los Angeles, 43, 45, MT
Price Guide A, Product 2, Dallas, 45.5, 48.5, MT



主要问题:
我基本上得到一个未知的XML文件,我必须将其显示为平面表
这是我可以处理的众多文件之一的示例。 我不提前知道DOM,因此无法使用给定的节点名称进行直接的LINQ查询。我尝试了重复执行DOM的尝试,但是当你处于递归时很难知道何时该写出记录。

额外信用:
从示例中,有时节点上有属性。如果有属性&#34; id&#34;我想在输出中包含该值。在这种情况下,我的输出将是:

e4c3db5c, Price Guide A, 1, Product 1, 40, Chicago, 48, 52, MT
e4c3db5c, Price Guide A, 1, Product 1, 71, Dallas, 45.5, 47, MT
e4c3db5c, Price Guide A, 2, Product 2, 40, Chicago, 48, 49, MT
e4c3db5c, Price Guide A, 2, Product 2, 101, Los Angeles, 43, 45, MT
e4c3db5c, Price Guide A, 2, Product 2, 71, Dallas, 45.5, 48.5, MT



提前谢谢。

修改
以下工作,但要求我提前了解XML结构。我希望概括这段代码:

var details =
from level1 in _xmlDoc.Root.Elements("PriceGuide")
from level2 in level1.Elements("Name")
from level3 in level2.Elements("Products")
from level4 in level3.Elements("Product")
from level5 in level4.Elements("Name")
from level6 in level5.Elements("Prices")
from level7 in level6.Elements("Price")
from level8a in level7.Elements("Region")
from level8b in level7.Elements("PriceLow")
from level8c in level7.Elements("PriceHigh")
from level8d in level7.Elements("UnitOfMeasure")
select new
{
                PriceGuideId = (string)level1.Attribute("id"),
                PriceGuideName = (string)level2.Value,
                ProductId = (string)level3.Attribute("id"),
                ProductName = (string)level4.Value,
                RegionId = (string)level8a.Attribute("id"),
                RegionName = (string)level8a.Value,
                PriceLow = (string)level8b.Value,
                PriceHigh = (string)level8c.Value,
                UnitOfMeasure = (string)level8d.Value,
};

我知道它没有多大帮助。

1 个答案:

答案 0 :(得分:0)

我不知道如何在linq中做到这一点。这是一个快速而又脏的代码

    XmlDocument dom = new XmlDocument();
    dom.LoadXml("<Pricing><PriceGuide id=\"e4c3db5c\"><Name>Price Guide A</Name><Products><Product id=\"1\"><Name>Product 1</Name><Prices><Price><Region id=\"40\">Chicago</Region><PriceLow>48</PriceLow><PriceHigh>52</PriceHigh><UnitOfMeasure>MT</UnitOfMeasure></Price><Price><Region id=\"71\">Dallas</Region><PriceLow>45.5</PriceLow><PriceHigh>47</PriceHigh><UnitOfMeasure>MT</UnitOfMeasure></Price></Prices></Product><Product id=\"2\"><Name>Product 2</Name><Prices><Price><Region id=\"40\">Chicago</Region><PriceLow>48</PriceLow><PriceHigh>49</PriceHigh><UnitOfMeasure>MT</UnitOfMeasure></Price><Price><Region id=\"101\">Los Angeles </Region><PriceLow>43</PriceLow><PriceHigh>45</PriceHigh><UnitOfMeasure>MT</UnitOfMeasure></Price><Price><Region id=\"71\">Dallas</Region><PriceLow>45.5</PriceLow><PriceHigh>48.5</PriceHigh><UnitOfMeasure>MT</UnitOfMeasure></Price></Prices></Product></Products></PriceGuide></Pricing>");

    List<KeyValuePair<int, String>> result = FlattenXML(dom.DocumentElement, "", 0);
    var q = result.Where(c => c.Key == result.Max(b => b.Key)).Select(b => b.Value.Substring(0, b.Value.Length - 1)).ToArray();

    Console.WriteLine(String.Join(System.Environment.NewLine, q));

    private List<KeyValuePair<int, String>> FlattenXML(XmlElement node, String parent, int level)
    {
        List<KeyValuePair<int, String>> result = new List<KeyValuePair<int, String>>();
        String detail = "";

        if (node.HasAttribute("id"))
            parent += node.Attributes["id"].InnerText + ",";

        if (node.InnerText == node.InnerXml && node.InnerText != "")
        {
            parent += node.InnerText + ",";
        }

        foreach (XmlElement child in node.ChildNodes)
        {
            if (child.InnerText == child.InnerXml && child.InnerText != "")
            {
                detail += child.InnerText + ",";
                level++;
            }

            if (child.FirstChild != child.LastChild)
            {
                List<KeyValuePair<int, String>> childResult = FlattenXML(child, parent + detail, level);
                result.AddRange(childResult);
            }
        }
        result.Add(new KeyValuePair<int, String>(level, parent + detail));
        return result;
    }
相关问题