解析XML并加载字典

本文关键字:字典 加载 XML 解析 | 更新日期: 2023-09-27 17:50:37

我想解析一个使用以下模式的XML文件,并提取"adif"answers"name"两个元素中的数据,并将它们放入Dictionary中。我真的不知道如何使用任何内建的。net类或HTML敏捷包来实现这一点。

有人能告诉我正确的方向吗?由于
<?xml version="1.0" encoding="utf-16"?>
 <xs:schema xmlns="http://www.clublog.org/cty/v1.0" attributeFormDefault="unqualified"         elementFormDefault="qualified" targetNamespace="http://www.clublog.org/cty/v1.1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="clublog">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="entities">
          <xs:complexType>
            <xs:sequence>
              <xs:element maxOccurs="unbounded" name="entity">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="adif" type="xs:decimal" />
                    <xs:element name="name" type="xs:string" />
                    <xs:element name="prefix" type="xs:string" />
                    <xs:element name="deleted" type="xs:boolean" />
                    <xs:element name="cqz" type="xs:unsignedByte" />
                    <xs:element name="cont" type="xs:string" />
                    <xs:element name="long" type="xs:decimal" />
                    <xs:element name="lat" type="xs:decimal" />
                    <xs:element minOccurs="0" name="start" type="xs:dateTime" />
                    <xs:element minOccurs="0" name="end" type="xs:dateTime" />
                    <xs:element minOccurs="0" name="whitelist" type="xs:boolean" />
                    <xs:element minOccurs="0" name="whitelist_start" type="xs:dateTime" />
                    <xs:element minOccurs="0" name="whitelist_end" type="xs:dateTime" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="exceptions">
          <xs:complexType>

我对实体节点以外的任何东西都不感兴趣。最多有400个这样的例子,而例外的例子有几万个。目前我得到的代码是

using (WebClient wc = new WebClient())
{
     wc.DownloadFile("https://secure.clublog.org/cty.php?api="API","Test.gz");
           var doc = new HtmlAgilityPack.HtmlDocument();
           using (var file = File.Open("Test.gz", FileMode.Open))
           using (var zip = new GZipStream(file, CompressionMode.Decompress))
           {
               doc.Load(zip);
           }
            Dictionary<string, string> dict = new Dictionary<string, string>();

就是这样。当然,HTML敏捷包没有文档,我对解析XML代码的理解是有限的。

这是我在哪里:XD包含有效的xml数据。

    private void button1_Click(object sender, EventArgs e)
    {
        var dict = (Dictionary<string, decimal>)null;
        using (WebClient wc = new WebClient())
        {
            wc.DownloadFile("https://secure.clublog.org/cty.php?api=", "Test.gz");

            using (var file = File.Open("Test.gz", FileMode.Open))
            {
                using (var zip = new GZipStream(file, CompressionMode.Decompress))
                {
                    using (var xmlReader = XmlReader.Create(zip))
                    {
                        //                            Dictionary<string, decimal> dict = new Dictionary<string, decimal>();
                        var xd = XDocument.Load(xmlReader);

                    }

所以这里是xml数据....两个记录。我试图将文件保存在服务器上,但它不允许我…

<?xml version="1.0" encoding="utf-8" ?>
-<clublog xmlns="http://www.clublog.org/cty/v1.0" date="2014-03-16T08:30:03+00:00">
  -<entities>
-<entity>
  <adif>1</adif>
  <name>CANADA</name>
  <prefix>VE</prefix>
  <deleted>FALSE</deleted>
   <cqz>5</cqz>
 <cont>NA</cont>
  <long>-80.00</long>
  <lat>45.00</lat>
</entity>

-<entity>
  <adif>2</adif>
  <name>ABU AIL IS</name>
<prefix>A1</prefix>
<deleted>TRUE</deleted>
<cqz>21</cqz>
<cont>AS</cont>
<long>45.00</long>
<lat>12.80</lat>
<end>1991-03-30T23:59:59+00:00</end>

解析XML并加载字典

像这样的东西应该为您工作:

var dict = (Dictionary<string, decimal>)null;
using (WebClient wc = new WebClient())
{
    var text = wc.DownloadString(
        "https://secure.clublog.org/cty.php?api=" + API);
    using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(text)))
    {
        using (var zip = new GZipStream(stream, CompressionMode.Decompress))
        {
            using (var xmlReader = XmlReader.Create(zip))
            {
                var xd = XDocument.ReadFrom(xmlReader);
                dict =
                xd
                    .Document
                    .Root
                    .Element(XName.Get("entities", "http://www.clublog.org/cty/v1.0"))
                    .Elements(XName.Get("entity", "http://www.clublog.org/cty/v1.0"))
                    .ToDictionary(
                        x => x.Element(XName.Get("name", "http://www.clublog.org/cty/v1.0")).Value,
                        x => (decimal)x.Element(XName.Get("adif", "http://www.clublog.org/cty/v1.0")));
            }
        }
    }
}

我假设你实际上想要一个给定"adif"类型的Dictionary<string, decimal>,但如果我错了,它应该很容易改变。

我的方法避免了所有与文件的混淆。

Jeenkies。我刚刚写了一个很好的集合来回答另一个问题,就像这样。如果你可以使用。net 3.5,你可以使用linq-to-xml,这将使这非常容易。

让我们开始吧。首先,您需要加载文档。看看这里和这里,你会得到一些帮助。我想第二个会对你更有帮助。

现在开始挖掘。由于您感兴趣的节点可能只有几层深,所以这应该不会太痛苦。在这一点上,我们遇到了两种设计(我能想到的),一层一层地凿掉它,把它炸成小块。由于您正在处理相当大的数据量,因此芯片可能更快,也可能不会。所以我将包括这两种设计,并让您从那里进行测试。

本设计将假设doc代表整个xml文档。

凿方法:

var elements = doc.Elements(xs:element).Where(el => el.Attribute("name").Value == "entities");

从那里应该是一个简单的问题,使用Elements()Attributes()的组合。

爆破方法只是用Descendants()代替Elements()。如果你处理的是近根级节点,我还是坚持使用切分方法。

现在是把它放入Dictionary。这应该会给你指明正确的方向。