【问题标题】:How to use Linq to pull certain data from XmlNodeList and load it into a dictionary in C#如何使用 Linq 从 XmlNodeList 中提取某些数据并将其加载到 C# 中的字典中
【发布时间】:2025-12-05 22:25:01
【问题描述】:

我有一些 C# 代码使用 System.Xml 解析 xml 文件,然后将某些数据从 xml 提取到字典中。

下面的代码可以工作,但它非常混乱,我不太喜欢它。我想把它折叠成一些简单的 Linq 调用,但我对 Linq 还是很陌生,不知道从哪里开始。任何人都可以提供一些关于如何 Linq-ify 这段代码的建议吗? (最好在方法语法中)

还因为代码将数据写入外部数据结构(字典),我不知道 Linq 会如何工作。

XML 示例数据:

<Localisation>

    <LOC_TAG value="tag_01" >
        <LOC_TEXT language="English" value="This is some text"/>
        <LOC_TEXT language="German" value="Das ist ein Text"/>
        <LOC_TEXT language="French" value="Il s'agit d'un texte"/>
    </LOC_TAG>

    <LOC_TAG value="tag_02" >
        <LOC_TEXT language="English" value="Another text string"/>
    </LOC_TAG>

</Localisation>

C#代码

Dictionary<string, string>  Strings = new Dictionary<string, string>();

XmlDocument xmlDoc = new XmlDocument(); 
xmlDoc.Load(new StringReader(locFile.text));

// Read each LOC_TAG and pull out its LOC_TEXT matching the required language into the dictionary
XmlNodeList locTags = xmlDoc.GetElementsByTagName("LOC_TAG");
foreach (XmlNode locTagNode in locTags)
{
    foreach (XmlNode child in locTagNode.ChildNodes)
    {
        if (child.Name == "LOC_TEXT" && 
            child.Attributes["language"].Value == Application.systemLanguage.ToString())
        {
            Strings.Add(locTagNode.Attributes["value"].Value, 
                        child.Attributes["value"].Value);
            break;
        }
    }
}

非常感谢任何帮助!

【问题讨论】:

  • 某种代码转换请求,应作为离题 IMO 关闭。

标签: c# linq


【解决方案1】:

由于查询是遍历XmlNodes的,所以我们可以随时用tag.ParentNode获取当前节点的父节点,这样工作就更简单了。

var strings = (from tag in locTags.Cast<XmlNode>().SelectMany(t => t.ChildNodes.Cast<XmlNode>())
    where tag.Name == "LOC_TEXT" && tag.Attributes["language"].Value == Application.systemLanguage.ToString()
    select new { key = tag.ParentNode.Attributes["value"].Value, value = tag.Attributes["value"].Value })
    .ToDictionary(t=>t.key, t=>t.value);

【讨论】:

    【解决方案2】:

    这是 LINQ 等价物:

    var language = Application.systemLanguage.ToString();
    var strings = XElement.Parse(xml)
        .XPathSelectElements("./LOC_TAG")
        .Select(x => new 
        {
            Tag = x.Attribute("value").Value,
            Text = x.XPathSelectElement($"./LOC_TEXT[@language='{language}']")
                ?.Attribute("value").Value
        })
        .Where(x => x.Text != null)
        .ToDictionary(x => x.Tag, x => x.Text);
    

    【讨论】:

    • 非常感谢。直到现在我什至还没有意识到有一个 Xml.Linq 命名空间......这非常有用!
    最近更新 更多