【问题标题】:Reading XML file into memory and searching it将 XML 文件读入内存并进行搜索
【发布时间】:2013-06-18 19:22:41
【问题描述】:

我有一个需要处理的给定 XML 文件。为了论证起见,假设我已经将它作为字符串加载。

<?xml version="1.0" encoding="UTF-8" ?> 
<GROUP ID="_group_id" ORDERINFO="00000" TITLE="Group 1">
  <GROUP ID="_group_id_2" TITLE="Group 2">
    <LO ID="_id_code1" LANG="enUS" TYPE="_cust" TITLE="Title 1" /> 
    <LO ID="_id_code2" LANG="enUS" TYPE="_cust" TITLE="Title 2" /> 
  </GROUP>
  <GROUP ID="_group_id_3" TITLE="Group 3">
    <LO ID="_id_code1" LANG="enUS" TYPE="_cust" TITLE="Title 1" /> 
    <LO ID="_id_code2" LANG="enUS" TYPE="_cust" TITLE="Title 2" /> 
  </GROUP>
</GROUP>

在一个给定的 XML 文件中可以有许多 LO 和许多 GROUP。我一直在尝试各种方法,但没有运气。我需要通过 ID 找到与给定字符串匹配的 LO,然后允许我将相应的 TYPE 和 TITLE 检索到字符串中,以便我可以使用它们进行处理。

我尝试将文件读入 XmlDocument,但加载后我无法弄清楚如何找到合适的元素。

抱歉在编辑之前发帖 - 有些文字被截断了

【问题讨论】:

标签: c# xml xmldocument


【解决方案1】:

您可以使用XmlDocumentXDocument 来解析Xml。

这是XDocument 的示例:

数据类:

public class Lo
{
    public string Id { get; set; }
    public string Lang { get; set; }
    public string Type { get; set; }
    public string Title { get; set; }
}

代码:

var document = XDocument.Parse(data);

var value = "_id_code1";

IEnumerable<Lo> result = 
    document.XPathSelectElements(".//LO")
            .Where(x => x.Attribute("ID").Value == value)
            .Select(x =>
                new Lo
                {
                    Id = x.Attribute("ID").Value,
                    Lang = x.Attribute("LANG").Value,
                    Type = x.Attribute("TYPE").Value,
                    Title = x.Attribute("TITLE").Value
                });

【讨论】:

    【解决方案2】:

    当加载到 XmlDocument 中时,您可以使用 XPath 来定位注释。

    例如:

    XmlNode group = xmlDocument.SelectSingleNode("/GROUP/GROUP[@ID='_group_id_2']");
    

    或者:

    XmlNodeList groups = xmlDocument.SelectNodes("/GROUP/GROUP");
    foreach(XmlNode group in groups)
    {
        string id = group.Attributes["ID"].Value;
    
    }
    

    这很容易。要获得更完整的演练,您应该搜索互联网。

    【讨论】:

    • 我一直在研究如何按照您的建议使用 XPath 来执行此操作,因为我更喜欢使用它,因为在这种情况下我可能会受限于 .net 2.0。我的问题是我不知道有多少组可能有或没有.. 所以我尝试编写一个跳过所有组内容的语句,但我每次都得到一个空结果: XmlNode group = xmlDocument.SelectSingleNode ("//LO[ID=" + strcourseID + "]");其中 strcourseID 是我存储在字符串中的课程 ID。
    • 整理好了。我用 SelectSingleNode("//LO[@ID=\"" + strcourseID + "\"]");这解决了问题。挑剔的语法;)
    【解决方案3】:
    【解决方案4】:

    最好将XAtribute 转换为字符串,然后访问其Value 属性(如果找不到某些属性,您将得到null 而不是异常)。这里的查询语法也更紧凑

    string id = "_id_code1";
    XDocument xdoc = XDocument.Parse(xml);
    
    var query = from lo in xdoc.Descendants("LO")
                where (string)lo.Attribute("ID") == id
                select new {
                    Id = (string)lo.Attribute("ID"),
                    Language = (string)lo.Attribute("LANG"),
                    Type = (string)lo.Attribute("TYPE"),
                    Title = (string)lo.Attribute("TITLE")
                };
    

    此查询将返回具有 Id、Language、Type、Title 属性的匿名对象序列。您可以使用foreach 枚举它们。

    【讨论】:

      【解决方案5】:

      我为此做了一个小测试应用程序,我将你的 xml 作为字符串包含在内。

                  var xmlMessage = @"keep your xml here, I removed due to formatting";
              var matchedElements = XDocument.Parse(xmlMessage).Descendants().Where(el => el.Name == "LO" && el.Attribute("ID").Value == "_id_code1");
              foreach (var el in matchedElements)
              {
                  Console.WriteLine("ElementName : {0}\nID = {1}\nLANG = {2}\nTYPE = {3}\nTITLE = {4}\n"
                      , el.Name.LocalName, el.Attribute("ID").Value, el.Attribute("LANG").Value, el.Attribute("TYPE").Value, el.Attribute("TITLE").Value);
      
               }
      

      这将帮助您获取 ID 为“_id_code”的所有 LO 元素,而与 GROUP 元素无关。 如果需要考虑组,将第二行代码替换为:

      var matchedElements = XDocument.Parse(xmlMessage).Descendants().Where(el => el.Parent != null && el.Parent.Attribute("ID").Value == "_group_id_2" && el.Name == "LO" && el.Attribute("ID").Value == "_id_code1");
      

      这里,我正在检查“_group_id_2”,你可以用你的组 id 替换。

      所需的命名空间:

      using System.Linq;
      using System.Xml;
      using System.Xml.Linq;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多