linq 然后XML查找返回上一个元素的值

vc9ivgsu  于 2022-12-06  发布在  其他
关注(0)|答案(2)|浏览(166)

我正在处理一个结构奇怪的XML文档,缺少ID和模糊的名称等。希望我的示例XML文档能为您描绘出一幅正确的画面。真实的的文档很大,有时嵌套了10层或更多层,这真的很让人头疼。
我需要做的是在名为Supplier/Name的节点中找到一个特定的值。但要找到这个值,我需要先在Var/Value中找到一个值,然后再查找。在我的示例中,我需要找到Var/Value CLR-111。
我不知道是用LINQ还是用XML文档做这个最好??我找到的壁橱是XMLNode使用前一个节点。但是我不知道如何先找到位置,然后再跳上两个。
简单的部分是定位元素,但不知道如何查找两个元素。这就是我轰炸的地方。

我需要返回的是ACME。

<?xml version="1.0" encoding="utf-8"?>
<Uni>
  <Job ID="Job1">
    <Manufacturing ID="MPG-1">
        <Factory>
            <SKUGroups ID="SKU-72">
                <Supplier>
                  <Name>ACME</Name>
                  <Details address="123 Bobs Road" Zip="90210" />
                </Supplier>
                <Type>Paint</Type>
                <Var>
                  <Name>ColorID</Name>
                  <Value>CLR-111</Value>
                </Var>
                <Supplier>
                  <Name>TomInc</Name>
                  <Details address="555 Jayne Lane" Zip="65986" />
                </Supplier>
                <Type>Tire</Type>
                <Var>
                  <Name>ColorID</Name>
                  <Value>CLR-2222</Value>
                </Var>
            </SKUGroups>
        </Factory>
    </Manufacturing>
  </Job>
</Uni>

XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.Load(myPath);
XmlNode blaa = doc.SelectSingleNode("descendant::SKUGroups[Var/Value='CLR-111']/Var/Name");
7dl7o3gd

7dl7o3gd1#

我从不后退。总是前进。我喜欢收集所有的数据,然后用字典来查找值。
下面是使用Xml linq。我强制转换而不是使用值,因此如果项为空,我不会得到异常
请参阅下面的代码

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

namespace ConsoleApplication2
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            List<Supplier> suppliers = new List<Supplier>();
            foreach(XElement job in doc.Descendants("Job"))
            {
                string jobId = (string)job.Attribute("ID");
                XElement manufacturing = job.Element("Manufacturing");
                string manufacturingId = manufacturing == null ? "" : (string)manufacturing.Attribute("ID");
                foreach(XElement skuGroup in job.Descendants("SKUGroups"))
                {
                    string skuGroupId = (string)skuGroup.Attribute("ID");
                    Supplier supplier = null;
                    foreach(XElement element in skuGroup.Elements())
                    {
                        switch(element.Name.LocalName)
                        {
                            case "Supplier":
                                supplier = new Supplier();
                                suppliers.Add(supplier);
                                supplier.jobId = jobId;
                                supplier.manufacturingId = manufacturingId;
                                supplier.skuGroupId = skuGroupId;
                                supplier.name = (string)element.Element("Name");
                                XElement details = element.Element("Details");
                                supplier.address = details == null ? "" : (string)details.Attribute("address");
                                supplier.zip = details == null ? "" : (string)details.Attribute("Zip");
                                break;
                            case "Type":
                                supplier.type = (string)element;
                                break;
                            case "Var":
                                supplier.varName = (string)element.Element("Name");
                                supplier.value = (string)element.Element("Value");
                                break;

                        }

                    }
                }

            }
            Dictionary<string, Supplier> dict = suppliers.GroupBy(x => x.value).ToDictionary(x => x.Key, y => y.FirstOrDefault());
            Supplier CLR_2222 = dict["CLR-2222"];
 
        }
 
    }
    public class Supplier
    {
        public string jobId { get; set; }
        public string manufacturingId { get; set; }
        public string skuGroupId { get; set; }
        public string name { get; set; }
        public string address { get; set; }
        public string zip { get; set; }
        public string type { get; set; }
        public string varName { get; set; }
        public string value { get; set; }
    }
}
6l7fqoea

6l7fqoea2#

您将需要搜索CLR-111节点(可能使用递归),一旦找到它,就可以使用node.ParentNode.ParentNode爬上树,回到Var节点。
Var节点上,您可以使用node.PreviousSibling在XmlDoc中向后遍历。
例如:

var clrXmlTextElement = ... // whatever the XmlText object element of the <Value>CLR-111</Value> node is when you find it.
var valueNode = clrNode.ParentNode; // <Value>CLR-111</Value>
var varNode = valueNode.ParentNode; // <Var>
var typeNode = varNode.PreviousSibling; // <Type>Paint</Type>
var supplierNode = typeNode.PreviousSibling; // <Supplier>
var supplierName = GetSupplierName(supplierNode); // ACME

string GetSupplierName(XmlNode supplierNode)
{
    foreach (XmlElement xmlElement in supplierNode.ChildNodes)
    {
        if (xmlElement.Name == "Name")
        {
            return xmlElement.InnerText;
        }
    }

    return "Error: no <Name> tag found in <Supplier> node.";
}

相关问题