【问题标题】:Retrieving data from XML file into variables将 XML 文件中的数据检索到变量中
【发布时间】:2017-12-06 06:58:25
【问题描述】:

我有一个具有以下结构的 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>

我需要将&lt;e1&gt; 元素中的数据放入某些变量中以供进一步使用。为此,我正在执行以下操作:

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 的新手,在C# 中与XML 合作。很好奇,是否有更好的方法来做到这一点?

【问题讨论】:

  • 嗨,给你的代码更新了我的答案,你能看看,这是有效的做事方式

标签: c# xml xml-parsing


【解决方案1】:

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

在我的代码中,我正在读取您给出的相关 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)Serialization 而不是这样做,这是一种更清晰的方法,您不必编写这么长的代码并记住事情。

为了进行 XML(de)Serialization,您需要与您的 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);

【讨论】:

  • 感谢您的建议。但是,你不认为最后我会做几乎相同的事情,只是将类元素值分配给变量。仅供参考,我必须为这些定义的变量赋值。所以使用类不会有任何优势。
【解决方案2】:

这是从 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
}

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2016-10-16
    • 1970-01-01
    • 2018-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-26
    • 1970-01-01
    • 2023-04-09
    相关资源
    最近更新 更多