在不知道元素顺序的情况下从上到下解析XML?

时间:2014-06-07 16:31:39

标签: c# xml visual-studio-2012

我正在尝试将XML解析为可运行的C#代码,以用于我正在处理的配置文件系统。这是XML代码:

<?xml version="1.0" encoding="utf-8"?>
<MCBuddy>
    <ProfileName>Profile Test 2</ProfileName>
    <MCScript>
        <Log>HELLO</Log>
        <Wait>100</Wait>
        <Status>Walking forward...</Status>
        <CameraMove X="-10" Y="-10" />
        <CameraMove X="-20" Y="10" />
        <CameraMove X="6" Y="15" />
        <CameraMove X="-10" Y="-10" />
        <CameraMove X="-20" Y="10" />
        <CameraMove X="6" Y="15" />
        <CameraMove X="-10" Y="-10" />
        <PressKey>D1</PressKey>
        <CameraMove X="-20" Y="10" />
        <CameraMove X="6" Y="15" />
        <CameraMove X="-10" Y="-10" />
        <CameraMove X="-20" Y="10" />
        <CameraMove X="6" Y="15" />
        <MoveLeft>5000</MoveLeft>
        <MoveForward>1000</MoveForward>
        <EndProfile />
    </MCScript>
</MCBuddy>

和C#代码:

while (time <= mb_runningTime.Value)
                {
                    time++;
                    foreach (var mright in doc.Descendants().Where(n => n.Name == "MoveRight"))
                    {
                        PlayerActions.MoveRight(Convert.ToInt32(mright.Value));
                    }

                    foreach (var mforward in doc.Descendants().Where(n => n.Name == "MoveForward"))
                    {
                        PlayerActions.MoveForward(Convert.ToInt32(mforward.Value));
                    }

                    foreach (var mback in doc.Descendants().Where(n => n.Name == "MoveBack"))
                    {
                        PlayerActions.MoveBack(Convert.ToInt32(mback.Value));
                    }

                    foreach (var mleft in doc.Descendants().Where(n => n.Name == "MoveLeft"))
                    {
                        PlayerActions.MoveLeft(Convert.ToInt32(mleft.Value));
                    }
                    foreach (var wait in doc.Descendants().Where(n => n.Name == "Wait"))
                    {
                        Task.Delay(Convert.ToInt32(wait.Value)).Wait();
                    }
                    foreach (var log in doc.Descendants().Where(n => n.Name == "Log"))
                    {
                        Function.Log(log.Value, 1, mb_logBox);
                    }
                    foreach (var state in doc.Descendants().Where(n => n.Name == "Status"))
                    {
                        mb_statusLabel.Text = state.Value;
                    }
                    foreach (var key in doc.Descendants().Where(n => n.Name == "PressKey"))
                    {
                        PlayerActions.PressKey((Keys)Enum.Parse(typeof(Keys), key.Value));
                    }
                    foreach (var msLeftClick in doc.Descendants().Where(n => n.Name == "MouseLeftClick"))
                    {
                        PlayerActions.MouseLeftClick();
                    }
                    foreach (var msRightClick in doc.Descendants().Where(n => n.Name == "MouseRightClick"))
                    {
                        PlayerActions.MouseRightClick();
                    }
                    foreach (var msLeftHold in doc.Descendants().Where(n => n.Name == "MouseLeftHold"))
                    {
                        PlayerActions.MouseLeftHold(Convert.ToInt32(msLeftHold.Value));
                    }
                    foreach (var msRightHold in doc.Descendants().Where(n => n.Name == "MouseRightHold"))
                    {
                        PlayerActions.MouseRightHold(Convert.ToInt32(msRightHold.Value));
                    }
                    foreach (var camMove in doc.Descendants().Where(n => n.Name == "CameraMove"))
                    {
                        Point move = new Point(Cursor.Position.X + Convert.ToInt32(camMove.Attribute("X").Value), Cursor.Position.Y + Convert.ToInt32(camMove.Attribute("Y").Value));
                        TimeSpan moveTime = new TimeSpan(0, 0, 0, 1);
                        LinearSmoothMove(move, moveTime);
                    }
                }

然而,我遇到了无法找到解析它的方法的问题,无论它以什么XML元素开头。如果我按照现在的方式保留它,它将按顺序解析它。我已经尝试了多种方法,但没有任何作用。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

您可以将其转换为查找

var xDoc = XDocument.Parse(xmlstring);
var lookup = xDoc.Descendants("MCScript")
                .First()
                .Elements()
                .ToLookup(x => x.Name.LocalName);

答案 1 :(得分:0)

你可以迭代MCScript下的元素,并根据元素的名称采取适当的行动:

        long time=0;
        foreach (var node in xd.Document
            .Element("MCBuddy")
            .Element("MCScript")
            .Elements())
        {
            if (time > mb_runningTime.Value)
            {
                 break;
            }
            time++;
            var ele = (XElement) node;
            switch (ele.Name.ToString())
            {
                case "Status":
                    mb_statusLabel.Text = ele.Value;
                    break;
                case "CameraMove":
                    var move = new Point(
                        Cursor.Position.X + Convert.ToInt32(ele.Attribute("X").Value),
                        Cursor.Position.Y + Convert.ToInt32(ele.Attribute("Y").Value));
                    TimeSpan moveTime = new TimeSpan(0, 0, 0, 1);
                    LinearSmoothMove(move, moveTime);
                break;
                    // others go here
                default:
                    Trace.WriteLine(ele.Name);
                    break;
            }
        }