我目前正在尝试获取一些XML数据,并将其重新编写为我正在处理的项目的另一种格式。现在我能够得到我正在做的事情的子节点,但我似乎无法让它将子节点分开。这是我得到的XML数据。
<Race xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Checkpoints>
<Vector3>
<X>237.477936</X>
<Y>936.0487</Y>
<Z>209.590744</Z>
</Vector3>
<Vector3>
<X>163.06778</X>
<Y>922.664856</Y>
<Z>208.251434</Z>
</Vector3>
<Vector3>
<X>74.3054</X>
<Y>1022.99408</Y>
<Z>215.625259</Z>
</Vector3>
<Vector3>
<X>20.2580948</X>
<Y>1040.94922</Y>
<Z>217.798935</Z>
</Vector3>
</Checkpoints>
</Race>
不,我试图抓住每个向量的X,Y和Z,并将它们构建成如下表所示,
{X, Y, Z, 8.0}
我目前正在做这个
XmlNodeList checkNodes = doc.SelectNodes("/Race/Checkpoints");
foreach (XmlNode aNode in checkNodes)
{
for (var w = 0; w < aNode.ChildNodes.Count; w++)
{
string checkpoint = "";
string xPos = aNode.ChildNodes[w].InnerText.ToString();
string yPos = aNode.ChildNodes[w].InnerText.ToString();
string zPos = aNode.ChildNodes[w].InnerText.ToString();
checkpoint = "{" + xPos + ", " + yPos + ", " + zPos + ", 8.0},";
xnTextBox.AppendText(Environment.NewLine + checkpoint);
}
}
但是我无法分解单个子组件,它只会输出所有这些组件
{237.477936936.0487209.590744, 237.477936936.0487209.590744, 237.477936936.0487209.590744, 8.0},
{163.06778922.664856208.251434, 163.06778922.664856208.251434, 163.06778922.664856208.251434, 8.0},
{74.30541022.99408215.625259, 74.30541022.99408215.625259, 74.30541022.99408215.625259, 8.0},
是的,我知道yPos和zPos的输出与zPos相同,因为我无法解决如何分割子节点的问题。任何帮助都会很棒,谢谢你。
修改
我已经将下面的答案创建成了一个类并且它可以工作,但是现在我有一个我需要获得的嵌套元素,但是当我尝试添加它时,它只返回一行而不是标题。
这是班级
using System;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;
[XmlRoot("Race")]
public class Race
{
[XmlElement(ElementName = "Checkpoints")]
public Checkpoints Checkpoints { get; set; }
[XmlElement(ElementName = "SpawnPoints")]
public SpawnPoints SpawnPoints { get; set; }
}
[XmlRoot("Vector3")]
public class Checkpoints
{
[XmlElement(ElementName = "Vector3")]
public List<Vector3> Vectors { get; set; }
}
[XmlRoot("Vector3")]
public class Vector3
{
[XmlElement(ElementName = "X")]
public double X { get; set; }
[XmlElement(ElementName = "Y")]
public double Y { get; set; }
[XmlElement(ElementName = "Z")]
public double Z { get; set; }
}
[XmlRoot("SpawnPoints")]
public class SpawnPoints
{
[XmlElement(ElementName = "SpawnPoint")]
public SpawnPoint SpawnPoint { get; set; }
}
[XmlRoot("Position")]
public class SpawnPoint
{
[XmlElement(ElementName = "Position")]
public List<Position> Positions { get; set; }
}
[XmlRoot("Position")]
public class Position
{
[XmlElement(ElementName = "X")]
public double X { get; set; }
[XmlElement(ElementName = "Y")]
public double Y { get; set; }
[XmlElement(ElementName = "Z")]
public double Z { get; set; }
}
这是我想要检索的XML数据。我需要得到X,Y,Z和标题。
<Race>
<SpawnPoints>
<SpawnPoint>
<Position>
<X>272.181335</X>
<Y>953.0988</Y>
<Z>211.16713</Z>
</Position>
<Heading>124.781677</Heading>
</SpawnPoint>
<SpawnPoint>
<Position>
<X>271.212</X>
<Y>957.0102</Y>
<Z>211.007156</Z>
</Position>
<Heading>121.86322</Heading>
</SpawnPoint>
<SpawnPoint>
<Position>
<X>270.4751</X>
<Y>961.3033</Y>
<Z>210.899719</Z>
</Position>
<Heading>118.801186</Heading>
</SpawnPoint>
<SpawnPoint>
<Position>
<X>270.059875</X>
<Y>965.9859</Y>
<Z>210.793045</Z>
</Position>
<Heading>106.5283</Heading>
</SpawnPoint>
<SpawnPoint>
<Position>
<X>269.029266</X>
<Y>970.9914</Y>
<Z>210.521118</Z>
</Position>
<Heading>107.501411</Heading>
</SpawnPoint>
<SpawnPoint>
</Race>
答案 0 :(得分:0)
您可能想要使用XmlSerializer课程
来自System.Xml.Serialization
命名空间。这是一个专门用于从XML派生的数据格式中提取数据的工具。这称为serialization。
它分两个主要步骤:
XmlSerializer
并使用您的数据致电XmlSerializer.Deserialize。在您的方案中,您将创建三个类。 Race
,Checkpoints
和Vector3
:
using System;
using System.Xml;
using System.Xml.Serialization;
// Represents the <Race> XML tag.
[XmlRoot("Race")]
class Race
{
// Because the <Checkpoints> tag is contained by the <Race> tag,
// the class representation of the <Checkpoints> tag should be contained
// by the class representation of the <Race> tag.
[XmlElement(ElementName = "Checkpoints")]
public Checkpoints Checkpoints { get; set; }
}
// Represents a <Checkpoints> XML tag.
[XmlRoot("Vector3")]
class Checkpoints
{
// Same as above but for <Vector3> tags.
[XmlElement(ElementName = "Vector3")]
public List<Vector3> Vectors { get; set; }
}
// Represents a <Vector3> XML tag.
[XmlRoot("Vector3")]
class Vector3
{
// The <X> element in the <Vector3> tag
[XmlElement(ElementName = "X")]
public double X { get; set; }
// Same
[XmlElement(ElementName = "Y")]
public double Y { get; set; }
// Same
[XmlElement(ElementName = "Z")]
public double Z { get; set; }
}
然后,您需要创建一个XmlSerializer
并使用它将XML数据反序列化为C#Race
对象。
// Wherever you get your XML from.
// You can also use a TextReader object,
// which means either a StreamReader or StringReader
// so you can use strings as well.
using(Stream xmlFile = File.OpenRead(""))
{
// Create a new XmlSerializer that deserializes
// instances of the Race class from XML.
XmlSerializer serializer = new XmlSerializer(typeof(Race));
Race race = (Race)serializer.Deserialize(xmlFile);
// Tada!
// You now have all of your data in
// a normal C# object.
foreach(Vector3 vector in race.Checkpoints.Vectors)
{
Console.WriteLine("X: {0} Y: {1} Z: {2}", vector.X, vector.Y, vector.Z);
}
}
另见:
修改强>
关键是SpawnPoints
不仅包含单 SpawnPoint
,还有很多。因此,您需要将public SpawnPoint SpawnPoint { get; set; }
更改为public List<SpawnPoint> Points { get; set; }
。对于Positions
类中的SpawnPoint
元素,反之亦然。
答案 1 :(得分:0)
这可以用LINQ简洁地完成:
XmlNodeList vecNodes = doc.SelectNodes("/Race/Checkpoints/Vector3");
var checkpoints =
from node in vecNodes.Cast<XmlNode>()
let dict = node.ChildNodes.Cast<XmlNode>().ToDictionary(n => n.Name, n => n.InnerText)
select "{" + dict["X"] + ", " + dict["Y"] + ", " + dict["Z"] + ", 8.0},";
foreach (var checkpoint in checkpoints)
Console.WriteLine(checkpoint);
{237.477936, 936.0487, 209.590744, 8.0},
{163.06778, 922.664856, 208.251434, 8.0},
{74.3054, 1022.99408, 215.625259, 8.0},
{20.2580948, 1040.94922, 217.798935, 8.0},
答案 2 :(得分:0)
我的偏好是使用xml linq并且只有一个类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
SpawnPoint.points = doc.Descendants("SpawnPoint").Select(x => new SpawnPoint() {
x = x.Descendants("X").Select(y => (double)y).FirstOrDefault(),
y = x.Descendants("Y").Select(y => (double)y).FirstOrDefault(),
z = x.Descendants("Z").Select(y => (double)y).FirstOrDefault(),
heading = (double)x.Element("Heading")
}).ToList();
}
}
public class SpawnPoint
{
public static List<SpawnPoint> points = new List<SpawnPoint>();
public double x { get; set; }
public double y { get; set; }
public double z { get; set; }
public double heading { get; set; }
}
}