【问题标题】:XML and HashtableXML 和哈希表
【发布时间】:2012-01-25 18:32:43
【问题描述】:

我有以下 XML 文件:

    <states>
      <state>
        <Name>a1</Name>
        <Address>a2</Address>
        <Name>b1</Name>
        <Address>b2</Address>
        <Name>c1</Name>
        <Address>c2</Address>
      </state>
      <state>
        <Name>aa1</Name>
        <Address>aa2</Address>
        <Name>bb1</Name>
        <Address>bb2</Address>
      </state>
    </states>

我需要将它存储在哈希表中并使用 C# 从中检索值。

谁能帮我解决这个问题?

【问题讨论】:

  • 您是否遇到任何问题或者您还没有尝试过什么?
  • XML 文件要这样组织吗?依赖于“名称后面的第一个地址元素是该名称的地址”,如此特定于订单并不是非常好的。
  • 你说 C# 3.0 和 C# 4.0,但你想要一个 Hashtable。一般来说,请查看 System.Collections.Generic.Dictionary 。 Hashtables 和 ArrayLists 在 2.0+ 中非正式地过时了
  • 在他的辩护中,他可能将HashTable 与仍然流行的HashSet 混淆了。

标签: c# xml c#-4.0 c#-3.0 hashtable


【解决方案1】:

我同意 Jon Skeet 的观点。这将是一种结构更好的方法,可以将与同一个人有关的信息包装在一个单一的(例如,&lt;Person&gt; 实体中)。您还应该为每个州提供一些名称或ID;否则,您的分组会显得随意。

<states>
  <state Name="Florida">
    <Person Name="a1">
       <Address>a2</Address>
    </Person>
    <Person Name="b1">
       <Address>b2</Address>
    </Person>
    <Person Name="c1">
       <Address>c2</Address>
    </Person>
  </state>
  <state Name="New York">
    <Person Name="aa1">
       <Address>aa2</Address>
    </Person>
    <Person Name="bb1">
       <Address>bb2</Address>
    </Person>
  </state>
</states>

以下是构建两级字典的方法。外部字典以州名作为关键字,并由包含居住在该州的人的字典进行赋值。内部字典以人名作为关键字,并以他们的地址为值。

XDocument document = XDocument.Parse(@"
    <states>
      <state Name=""Florida"">
        <Person Name=""a1"">
            <Address>a2</Address>
        </Person>
        <Person Name=""b1"">
            <Address>b2</Address>
        </Person>
        <Person Name=""c1"">
            <Address>c2</Address>
        </Person>
      </state>
      <state Name=""New York"">
        <Person Name=""aa1"">
            <Address>aa2</Address>
        </Person>
        <Person Name=""bb1"">
            <Address>bb2</Address>
        </Person>
      </state>
    </states>");

IDictionary<string, Dictionary<string, string>> dictionary =                
    document.Root.Elements("state").ToDictionary(
        state => state.Attribute("Name").Value,
        state => state.Elements("Person").ToDictionary(
            person => person.Attribute("Name").Value,
            person => person.Element("Address").Value));

// To get address of "a1" living in Florida:
string addr1 = dictionary["Florida"]["a1"];      // gives "a2"

// To get address of "bb1" living in New York:
string addr2 = dictionary["New York"]["bb1"];    // gives "bb2"

因此,要获取居住在城市C 的人X 的地址,您只需要访问dictionary[C][X]

编辑:回复评论:

您可以通过首先删除他们的条目(从内部字典中)然后重新添加它(以新名称作为键)来更改一个人的名字。

例如,将名称 "aa1" 更改为 "aa2"

Dictionary<string, string> innerDictionary = dictionary["New York"];
string address = innerDictionary["aa1"];
innerDictionary.Remove("aa1");
innerDictionary.Add("xx1", address);

也就是说,如果您经常需要更改密钥,Dictionary&lt;TKey, TValue&gt; 可能不是最佳结构。

【讨论】:

  • 感谢您的回答。它对我帮助很大。我是 C# 新手,所以对我来说有点问题。
  • Douglas,这是一些非常紧凑的代码。通常我只是将所有内容都保留在 XML 文档中,然后将 XPath 与 SelectSingleNode("/states/state[@name='Florida']/person[@name='a1']" 一起使用,但是那个 IDictionary 代码非常酷也可以这样做。
  • @Douglas,有没有什么方法可以编辑字典中的 aa1 人名??
  • 谢谢威廉! (虽然这个建议实际上是 Krishh 的。)如果您需要快速执行大量查找,该字典是有利的。根据 MSDN:“使用其键检索值非常快,接近 O(1),因为 Dictionary&lt;TKey, TValue&gt; 类是作为哈希表实现的。” Krishh:我在帖子中回复了。
猜你喜欢
  • 1970-01-01
  • 2013-03-21
  • 2018-10-13
  • 2010-12-26
  • 2011-01-11
  • 2023-03-31
  • 2016-08-04
  • 2019-04-04
  • 2023-03-27
相关资源
最近更新 更多