web-dev-qa-db-ja.com

XML解析-単純なXMLファイルを読み取り、値を取得する

学習目的でタスクスケジューリングプログラムを作成しました。現在、スケジュールされたタスクをプレーンテキストとして保存し、Regexを使用して解析しています。これは乱雑に見え(コード上)、あまり一貫性がありません。

代わりに、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. 最初のTaskタグをロードします。
  3. そのタスクで、Name、Location、およびArgumentsタグの値を取得します。
  4. 次に、RunWhenタグを開き、TimeタグとDateタグの値を取得します。
  5. その後、Daysタグを開き、内部の個々のタグの値を取得します。
  6. Enabledの値を取得します。
  7. 次のタスクをロードし、タスク内のすべてのタスクタグが解析されるまで手順3-> 7を繰り返します。

この方法であなたがそれを行うことができると確信しています。XMLで物事を行うための非常に多くの異なる方法があるので、私はそれを解決することができません。しかし、私がこれまでに行ったことは、おそらくXPathDocumentとXPathNodeIteratorを使用しているということです。

誰かが私に例を見せたり、これがどのように行われるか説明してくれたら、とてもうれしいです。

30
Lucidity

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);
    }
}
44
Serghei

通常は XmlDocument を使用します。インターフェイスは非常に単純です。

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

辞書に似たノードにアクセスできます:

var tasks = doc["Tasks"];

ノードのすべての子をループします。

11
ChrisWue

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);
 }
2
BreakHead

DataSetクラスに精通していますか?

DataSetload XML文書にも使用でき、反復が簡単になります。

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

DataSet dt = new DataSet();
dt.ReadXml(@"c:\test.xml");
2
WraithNath
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)
                {

                }      
            }       
    }
}
0
DivyaPrakash