在不知道元素顺序的情况下从上到下解析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元素开头,都无法找到一种方法来解析它。如果我保持它现在的样子,它就会按这个顺序解析它。我已经尝试了多种方法做到这一点,但没有工作。什么好主意吗?
可以转换为查找
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;
}
}