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

本文关键字:从上到下 XML 情况下 不知道 元素 顺序 | 更新日期: 2023-09-27 18:07:07

我正在尝试将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元素开头,都无法找到一种方法来解析它。如果我保持它现在的样子,它就会按这个顺序解析它。我已经尝试了多种方法做到这一点,但没有工作。什么好主意吗?

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

可以转换为查找

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

您可以遍历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;
            }
        }