【问题标题】:Read xml from file从文件中读取 xml
【发布时间】:2015-07-14 16:37:44
【问题描述】:

我在从 xml 文件中读取信息时遇到了一点问题...

传递给我的文件有数千行。我只对其中的 300 - 400 行感兴趣。当用户完成他的操作并且要读取的数据可以存储在List<string>中时,我不需要将任何数据写回xml。

我在网上找到了使用XmlTextReader 读取数据的解决方案。所以我不必创建一个类并使用序列化器。但似乎我使用了XmlTextReader 错误。或许你能帮帮我……

这就是 xml 的样子:

<?xml version="1.0" encoding="utf-8"?>
<ProjectConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi="http://www.w3.org/2001/XMLSchema-instance">
  <ProjectLists xmlns="...">
    <ProjectList>
  ... // not interested in this data
   </ProjectList>
  <ProjectList>
  <ListNode>
    <Name>Test_Environment</Name>
    <Children>
      <ListNode>
        <Name>yyy</Name>
        <Children>
          <ListNode>
            <Name>205 (ST)</Name>
            <Children>
              <ListNode>
                <Name>098-0031</Name>
                <Children />
              </ListNode>
              <ListNode>
                <Name>098-0032</Name>
                <Children />
              </ListNode>
              //more ListNodes...
            </Children>
          </ListNode>
          <ListNode>
            <Name>old</Name>
            <Children>
              <ListNode>
                <Name>W098-32</Name>
                <Children />
              </ListNode>
            </Children>
          </ListNode>
        </Children>
      </ListNode>
      <ListNode>
        <Name>xxx</Name>
        <Children />
      </ListNode>
      <ListNode>
        <Name>098-0001</Name>
        <Children />
      </ListNode>
      <ListNode>
        <Name>098-0011</Name>
        <Children />
      </ListNode>
      // More List Nodes
    </Children>
  </ListNode>
  <ListNode>
    // more List Nodes
  </ListNode>
</ProjectList>
<ProjectList>
  //more uninteresting ProjectLists...
</ProjectList>

我只对最内部名称元素的Value 感兴趣(前两个是“098-0031”和“098-0032”)。

这是我的代码:

while (reader.Read()) {
            switch (reader.NodeType) {
                case XmlNodeType.Element:
                    {
                        if (reader.Name == "Name") {
                            reader.Read();
                            if (reader.Value == "Test_Environment") {
                                reader.ReadToDescendant("Children");
                                if (reader.Name == "Children") {
                                    reader.ReadToDescendant("Children");

                                }
                            }
                        }
                    }
                    break;
            }
        }

但是条件reader.Name == "Children" 永远不会满足......有人可以向我解释为什么。也许向我展示一种将这些值存储在List&lt;string&gt; 中的简单方法?提前致谢!

编辑:我编辑了 xml。很抱歉,但从我的 xml 中过滤掉不必要的混乱部分真的很难......

【问题讨论】:

  • 可以使用其他类似Linq2XML吗?
  • @SkyFang 绝对有可能

标签: c# xml


【解决方案1】:
static void GetMostInnerName()
{
    string xml = @"<ProjectConfiguration xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xsi=""http://www.w3.org/2001/XMLSchema-instance"">
<ProjectLists>   
<ProjectList>
<ListNode>
<Name>Test_Environment</Name>
<Children>
<ListNode>
<Name>yyy</Name>
<Children>
<ListNode>
<Name>205 (ST)</Name>
<Children>
<ListNode>
<Name>098-0031</Name>
<Children />
</ListNode>
<ListNode>
<Name>098-0032</Name>
<Children />
</ListNode>
</Children>
</ListNode>
<ListNode>
<Name>old</Name>
<Children>
    <ListNode>
    <Name>W098-32</Name>
    <Children />
    </ListNode>
</Children>
</ListNode>
</Children>
</ListNode>
<ListNode>
<Name>xxx</Name>
<Children>
<ListNode>
<Name>098-0001</Name>
<Children />
</ListNode>
<ListNode>
<Name>098-0011</Name>
<Children />
</ListNode>
</Children>
</ListNode>
// more List Nodes
</Children>
</ListNode>
</ProjectList></ProjectLists>
</ProjectConfiguration>";
    XElement root = XElement.Parse(xml).Element("ProjectLists");
    //var xmlns = root.GetDefaultNamespace();
    //Console.WriteLine(xmlns);
    var eles = root.Elements("ProjectList").SelectMany(x => x.Elements("ListNode"));
    List<string> list = new List<string>();
    foreach (var ele in eles)
    {
        Loop(ele, list);
    }
    list.ForEach(x =>
    {
        Console.WriteLine(x);
    });
}
static void Loop(XElement ele, List<string> list)
{
    var child = ele.Element("Children");
    if (child != null && child.HasElements)
    {
        foreach (var e in child.Elements("ListNode"))
        {
            Loop(e, list);
        }
    }
    else
    {
        list.Add(ele.Element("Name").Value);
    }
}

因为你的xml有很多像ProjectList这样的节点,所以我在这里使用SelectMany,并添加root元素进行测试,最后输出是

098-0031
098-0032
W098-32
098-0001
098-0011

【讨论】:

  • 谢谢,但eles 对我来说是空的
  • 是的,你应该使用root.Element(xxx).Element(yyy).Elements("ProjectList"),因为我不知道你的树结构
  • 你能用正确的值显示xmlns吗,这很重要
【解决方案2】:
private static void FillNames(XElement container, List<string> result)
{
    XElement[] listNodes = container.Elements("ListNode").ToArray();
    if (!listNodes.Any())
        return;

    foreach (XElement listNode in listNodes)
    {
        XElement nameElement = listNode.Element("Name");
        if (nameElement == null)
            continue;

        XElement childrenElement = listNode.Element("Children");
        if (childrenElement == null)
            continue;

        if (!childrenElement.HasElements)
            result.Add(nameElement.Value);
        else
            FillNames(childrenElement, result);
    }
}

static void Main(string[] args)
{
    var result = new List<string>();

    string xml = Resources.Xml; // TODO: put your xml here

    XDocument doc = XDocument.Parse(xml);
    if (doc.Root == null)
        return;

    XElement[] projects = doc.Root.Elements("ProjectList").ToArray();

    foreach (XElement project in projects)
        FillNames(project, result);
}

【讨论】:

    【解决方案3】:

    这有帮助吗?:)

                    string path = @"path.xml";
    
                       if(File.Exists(path)){
                    XmlTextReader reader = new XmlTextReader(path);
    
                    Console.WriteLine("");
                    while (reader.Read())
                    {
                        switch (reader.NodeType)
                        {
    
                            case XmlNodeType.Element:  
                                Console.Write("<" + reader.Name);
                                Console.WriteLine(">");
                                break;
    
                            case XmlNodeType.Text:   
                                Console.WriteLine(reader.Value);
                                break;
                            case XmlNodeType.EndElement: 
                                Console.Write("</" + reader.Name);
                                Console.WriteLine(">");
                                break;
                        }
                    }
                    Console.ReadLine();
                       }else{
                           Console.WriteLine("Error file not found");
                       }
    

    【讨论】:

      【解决方案4】:

      这是什么语言?通过使用标签,您可以像 JSON 一样遍历 XML。

      【讨论】:

        【解决方案5】:

        使用LinqToXml

        var xDocument = XDocument.Parse("yourXmlString");
                XNamespace ns = xDocument.Root.GetDefaultNamespace();
                var result = (from e in xDocument
                                  .Descendants(ns + "ListNode").Descendants(ns + "Children")
                                  .Descendants(ns + "ListNode").Descendants(ns + "Children")
                                  .Descendants(ns + "ListNode").Descendants(ns + "Children")
                                  .Descendants(ns + "ListNode")
                                   select e.Element(ns + "Name").Value).ToList();
        

        【讨论】:

        • 非常感谢您的帮助。为什么您的第一行会抛出 XmlException(第 1 行位置 1 中的无效数据),而这一行不会:XmlTextReader reader = new XmlTextReader("MyXmlString");?我的第一行如下所示:&lt;?xml version="1.0"?&gt;
        • @user3596113 在双引号前使用\` 作为&lt;?xml version=\"1.0\"?&gt;
        • 如果你想使用硬编码的 XML 字符串,那么在双引号之前使用反斜杠作为 &lt;?xml version=\"1.0\"?&gt; 否则如果你从服务器获取则不需要
        • 好的,谢谢。到目前为止它正在工作,但结果对我来说是空的
        • 您是否使用与问题中相同的 XML?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-07-09
        • 1970-01-01
        • 2016-05-19
        • 1970-01-01
        • 2012-03-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多