【问题标题】:XML Parsing - Read a Simple XML File and Retrieve ValuesXML 解析 - 读取一个简单的 XML 文件并检索值
【发布时间】:2011-08-02 00:54:51
【问题描述】:

我为学习目的编写了一个任务调度程序。目前,我将计划任务保存为纯文本,然后使用正则表达式对其进行解析。这看起来很混乱(代码方面)并且不是很连贯。

我想从 XML 文件加载计划任务,我已经搜索了很多以找到一些解决方案,但我无法让它按我想要的方式工作。

我写了一个这样结构的 XML 文件来存储我的数据:

<Tasks>
    <Task>
        <Name>Shutdown</Name>
        <Location>C:/WINDOWS/system32/shutdown.exe</Location>
        <Arguments>-s -f -t 30</Arguments>
        <RunWhen>
            <Time>8:00:00 a.m.</Time>
            <Date>18/03/2011</Date>
            <Days>
                <Monday>false</Monday>
                <Tuesday>false</Tuesday>
                <Wednesday>false</Wednesday>
                <Thursday>false</Thursday>
                <Friday>false</Friday>
                <Saturday>false</Saturday>
                <Sunday>false</Sunday>
                <Everyday>true</Everyday>
                <RunOnce>false</RunOnce>
            </Days>
        </RunWhen>
        <Enabled>true</Enabled>
    </Task>
</Tasks>

我想解析数据的方式是这样的:

  1. 打开Tasks.xml
  2. 加载第一个任务标签。
  3. 在该任务中检索名称、位置和参数标签的值。
  4. 然后打开 RunWhen 标记并检索 Time 和 Date 标记的值。
  5. 然后打开 Days 标签并检索其中每个标签的值。
  6. 检索已启用的值。
  7. 加载下一个任务并重复步骤 3 -> 7,直到解析完 Tasks 中的所有 Task 标签。

我很确定你可以这样做,但我无法解决,因为在 XML 中有很多不同的方法来做事,我有点不知所措。但是到目前为止,我很可能会使用 XPathDocument 和 XPathNodeIterator 对吗?

如果有人可以向我展示一个示例或向我解释如何做到这一点,我会非常高兴。

【问题讨论】:

    标签: c# .net xml parsing


    【解决方案1】:

    解析xml的简单方法是使用LINQ to XML

    例如,您有以下 xml 文件

    <library>
        <track id="1" genre="Rap" time="3:24">
            <name>Who We Be RMX (feat. 2Pac)</name>
            <artist>DMX</artist>
            <album>The Dogz Mixtape: Who's Next?!</album>
        </track>
        <track id="2" genre="Rap" time="5:06">
            <name>Angel (ft. Regina Bell)</name>
            <artist>DMX</artist>
            <album>...And Then There Was X</album>
        </track>
        <track id="3" genre="Break Beat" time="6:16">
            <name>Dreaming Your Dreams</name>
            <artist>Hybrid</artist>
            <album>Wide Angle</album>
        </track>
        <track id="4" genre="Break Beat" time="9:38">
            <name>Finished Symphony</name>
            <artist>Hybrid</artist>
            <album>Wide Angle</album>
        </track>
    <library>
    

    要读取此文件,您可以使用以下代码:

    public void Read(string  fileName)
    {
        XDocument doc = XDocument.Load(fileName);
    
        foreach (XElement el in doc.Root.Elements())
        {
            Console.WriteLine("{0} {1}", el.Name, el.Attribute("id").Value);
            Console.WriteLine("  Attributes:");
            foreach (XAttribute attr in el.Attributes())
                Console.WriteLine("    {0}", attr);
            Console.WriteLine("  Elements:");
    
            foreach (XElement element in el.Elements())
                Console.WriteLine("    {0}: {1}", element.Name, element.Value);
        }
    }
    

    【讨论】:

    • 对于那些想要复制/粘贴此代码的人,您还需要添加“使用 System.Xml.Linq;”
    【解决方案2】:

    我通常为此使用XmlDocument。界面非常简单:

    var doc = new XmlDocument();
    doc.LoadXml(xmlString);
    

    您可以访问类似于字典的节点:

    var tasks = doc["Tasks"];
    

    并遍历一个节点的所有子节点。

    【讨论】:

    • 你能看到我的question 之一关于 xml 响应吗?
    【解决方案3】:

    试试XmlSerialization

    试试这个

    [Serializable]
    public class Task
    {
        public string Name{get; set;}
        public string Location {get; set;}
        public string Arguments {get; set;}
        public DateTime RunWhen {get; set;}
    }
    
    public void WriteXMl(Task task)
    {
        XmlSerializer serializer;
        serializer = new XmlSerializer(typeof(Task));
    
        MemoryStream stream = new MemoryStream();
    
        StreamWriter writer = new StreamWriter(stream, Encoding.Unicode);
        serializer.Serialize(writer, task);
    
        int count = (int)stream.Length;
    
         byte[] arr = new byte[count];
         stream.Seek(0, SeekOrigin.Begin);
    
         stream.Read(arr, 0, count);
    
         using (BinaryWriter binWriter=new BinaryWriter(File.Open(@"C:\Temp\Task.xml", FileMode.Create)))
         {
             binWriter.Write(arr);
         }
     }
    
     public Task GetTask()
     {
         StreamReader stream = new StreamReader(@"C:\Temp\Task.xml", Encoding.Unicode);
         return (Task)serializer.Deserialize(stream);
     }
    

    【讨论】:

    • 你能看到我的question 之一关于 xml 响应吗?
    【解决方案4】:

    您熟悉DataSet 类吗?

    DataSet 也可以load XML 文档,您可能会发现它更容易迭代。

    http://msdn.microsoft.com/en-us/library/system.data.dataset.readxml.aspx

    DataSet dt = new DataSet();
    dt.ReadXml(@"c:\test.xml");
    

    【讨论】:

    • -1:DataTable 无法加载所有 XML,只能加载与关系数据库模式匹配的 XML。
    • @JohnSaunders - 想详细说明一下吗?我刚刚用有问题的 xml 文件尝试了上面的代码,读取它没有问题
    • 正如我所说。 DataSet 无法处理任意 XML。它只能处理映射到“关系”结构的 XML。您可能希望在 XML 中使用的许多“正常”事物不适用于 DataSet。例如,&lt;root&gt;&lt;parent1&gt;&lt;child/&gt;&lt;/parent1&gt;&lt;parent2&gt;&lt;child/&gt;&lt;/parent2&gt;&lt;/root&gt;。关系表不能有两个父级,因此这不适用于 DataSet
    • @JohnSaunders - 谢谢,虽然它适用于上述 xml,但当有多个不同的任务(完整的 xml 文件)时,它可能不起作用。如果我以后再次使用它时遇到问题,将不得不尝试并记住
    【解决方案5】:
    class Program
    {
    
        static void Main(string[] args)
        {
    
            //Load XML from local
            string sourceFileName="";
            string element=string.Empty;
            var FolderPath=@"D:\Test\RenameFileWithXmlAttribute";
    
                string[] files = Directory.GetFiles(FolderPath, "*.xml");
                foreach (string xmlfile in files)
                {
                    try
                    {
                        sourceFileName = xmlfile;
                        XElement xele = XElement.Load(sourceFileName);
                        string convertToString = xele.ToString();
                        XElement parseXML = XElement.Parse(convertToString);
                        element = parseXML.Descendants("Meta").Where(x => (string)x.Attribute("name") == "XMLTAG").Last().Value;
                        DirectoryInfo CurrentDate = Directory.CreateDirectory(DateTime.Now.ToString("yyyy-MM-dd"));
                        string saveWithThisName= Path.Combine(CurrentDate.FullName, element);
                        File.Copy(sourceFileName, saveWithThisName,true);                      
                    }
                    catch(Exception ex)
                    {
    
                    }      
                }       
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-21
      • 2013-06-13
      相关资源
      最近更新 更多