将XML文件中的数据检索到变量中

时间:2017-12-06 06:58:25

标签: c# xml xml-parsing

我有一个XML文件,它具有以下结构:

<root>
    <body>
        <e1>
            <en>
                <tag1>testt1</tag1>
                <tag2 user="anonym">testt2</tag2>
                <tag3>testt3</tag3>
                <tag4>testt4</tag4>
                <tag5>
                    <t51>tttt</t51>
                    <t52>ttt</t52>
                    <t53>ttt</t53>
                </tag5>
            </en>
            <r1>1</r1>
            <r2>
                <tr1>0</tr1>
            </r2>
        </e1>
        <r1>
        </r1>
        <r2>
        </r2>
    </body>
    <info>
    </info>
</root>

我需要将<e1>元素中的数据转换为某些变量以供进一步使用。为此,我正在做以下事情:

foreach (XElement elem in xmlDoc.Descendants("body").Descendants("e1"))
{
    tag1 = elem.Element("en").Element("tag1").Value;
    tag2 = elem.Element("en").Element("tag2").Value;
    tag2a = elem.Element("en").Element("tag2").Attribute("user").Value;
    tag3 = elem.Element("en").Element("tag3").Value;
    tag4 = elem.Element("en").Element("tag4").Value;
    t51 = elem.Element("en").Element("tag5").Element("t51").Value;
    t52 = elem.Element("en").Element("tag5").Element("t52").Value;
    t53 = elem.Element("en").Element("tag5").Element("t53").Value;
    r1 = elem.Element("r1").Value;
    tr1 = elem.Element("r2").Element("tr1").Value;
}

它工作正常,但我认为,它看起来不是最好的方式。我是XDocuments的新用户,并且在XML中与C#合作。好奇,如果还有更好的方法可以做到这一点吗?

2 个答案:

答案 0 :(得分:0)

我找到了很容易做到的方法,下面是我的代码,

在我的代码中,我正在读取你所提供的xml字符串的值,并在阅读后将其存储到字典对象中。

   static Dictionary<string, string> ele = new Dictionary<string, string>();
    private static void ReadAllElements(XElement node)
    {
        if (node.HasElements)
        {
            foreach (var element in node.Elements())
                ReadAllElements(element);
        }
        else
        {
            ele[node.Name.ToString()] = node.Value;
            if (node.HasAttributes)
            {
                foreach (var att in node.Attributes())
                    ele[node.Name.ToString() + att.Name.ToString()] = att.Value;
            }
            return;
        }
    }

    public static void Main()
    {
        FileStream fs = new FileStream("XMLFile1.xml", FileMode.Open);
        XDocument xDoc = XDocument.Load(fs);
        var rows=(from row in xDoc.Descendants("e1").Elements()
                     select row).ToList();
        foreach (XElement node in rows)
            ReadAllElements(node);
        foreach (var keypair in ele)
            Console.WriteLine($"{keypair.Key} : {keypair.Value}");
        Console.ReadLine();
 }

输出

tag1 : testt1
tag2 : testt2
tag2user : anonym
tag3 : testt3
tag4 : testt4
t51 : tttt
t52 : ttt
t53 : ttt
r1 : 1
tr1 : 0

我建议你使用XML(de)序列化而不是这样做,这是非常明确的方法,你不必做这么长的代码并记住事情。

对于XML(de)序列化,您需要将类似于xml结构的类。因此,为了获得类似的结构,您可以使用visual studio:Visual Studio Generate Class From JSON or XML

  XmlSerializer serializer = new
    XmlSerializer(typeof(ClassName you create));
    FileStream fs = new FileStream(filename, FileMode.Open);
    XmlReader reader = XmlReader.Create(fs);
    ClassName i;
    i = (ClassName)serializer.Deserialize(reader);

答案 1 :(得分:0)

以下是从xml中提取数据的另一种快速而精确的方法。使用Cinchoo ETL - 一个开源库从CSV / XML / Json文件中提取数据。

using (var parser = new ChoXmlReader("sample10.xml").WithXPath("/root/body/e1")
    .WithField("tag1", xPath: "en/tag1")
    .WithField("tag2", xPath: "en/tag2")
    .WithField("tag2a", xPath: "en/tag2/@user")
    .WithField("tag3", xPath: "en/tag3")
    .WithField("tag4", xPath: "en/tag4")
    .WithField("t51", xPath: "en/tag5/t51")
    .WithField("t52", xPath: "en/tag5/t52")
    .WithField("t53", xPath: "en/tag5/t53")
    .WithField("r1", xPath: "r1")
    .WithField("r2", xPath: "r2/tr1")
)
{
    foreach (dynamic rec in parser)
    {
        Console.WriteLine(rec.DumpAsJson());

        //To access individual memnbers as below
        //Console.WriteLine(rec.tag1);
        //Console.WriteLine(rec.tag2);
    }
}

输出:

{
  "tag1": "testt1",
  "tag2": "testt2",
  "tag2a": "anonym",
  "tag3": "testt3",
  "tag4": "testt4",
  "t51": "tttt",
  "t52": "ttt",
  "t53": "ttt",
  "r1": 1,
  "r2": 0
}

希望这有帮助。