在c#中获取上两层XML中的父节点值
本文关键字:XML 两层 父节点 获取 | 更新日期: 2023-09-27 18:16:20
我有如下示例所示的XML -
<?xml version="1.0" encoding="UTF-8"?>
<Model>
<Part Id="0">
<Specs>
<Spec Id = "100" name="SpecNode">
</Spec>
</Specs>
</Part>
</Model>
这是我的XML示例说明,因此请忽略任何输入错误。
所以在这个XML中,我能够检索Spec作为XPathNodeIterator对象。所以现在我想去部分节点并获得它的Id属性值。因为我有XPathNodeIterator对象,它指向Spec和Part节点,位于两层以上。
所以请指导我应该做的代码更改,以达到这一要求。
这是我的代码片段。
System.Xml.XPath.XPathDocument xmlDoc = new System.Xml.XPath.XPathDocument("my.xml");
XPathNavigator xmlNav = xmlDoc.CreateNavigator();
XPathNodeIterator nodes = xmlNav.Select(XPathExpression.Compile(@"//Part/Specs/Spec[@name="SpecNode"]))
上面的代码示例给了我节点对象。所以我现在的要求是得到部分节点的Id值上面两个级别。
您可以使用以下LINQ来检索Part-node
的Id-attribute
:
const string file = @"D:'Temp'file.xml";
// Load the file.
XDocument doc = XDocument.Load(file);
// Retrieve the attribute selecting the Part-Element and then its Id-attribute.
XAttribute partAttribute = doc.Root.Descendants("Part").Select(element => element.Attribute("Id")).FirstOrDefault();
// Call partAttribute.Value to retrieve its' value.
Console.WriteLine(partAttribute.Value);
Console.Read();
输出:0。
请注意,如果Part-Element不存在,则会在partAttribute上抛出NullReferenceException。值调用。如果Part-Element存在但Id不存在,也会发生同样的情况。使用if(partAttribute != null)
来确定该值是否存在。
如果您将获得很多部分节点,您可以使用KeyValuePairs按ID对它们进行排序:
List<KeyValuePair<int, XElement>> partNodesWithIDValue = new List<KeyValuePair<int, XElement>>();
// Get a list of all Part-nodes where an ID exists.
List<XElement> partNodes = doc.Root.Descendants("Part").Where(element => element.Attribute("Id") != null).ToList();
// Sort the XElements according to their ID-value.
foreach (XElement partNode in partNodes)
{
KeyValuePair<int, XElement> elementWithAttribID = new KeyValuePair<int, XElement>(int.Parse(partNode.Attribute("Id").Value), partNode);
partNodesWithIDValue.Add(elementWithAttribID);
}
// Get a list of all Part-elements where the ID = 1.
List<XElement> partNodesWithID1 = partNodesWithIDValue.Where(kvp => kvp.Key == 1).Select(kvp => kvp.Value).ToList();
考虑到您希望保留原始代码,对XPath做一个简单的更改就可以了:
XPathNodeIterator nodes = xmlNav.Select(XPathExpression.Compile(@"//Part[@Id]"));
//Part[@Id]
: //Part
选择所有命名为Part
的节点。添加[@Id]
使其只选择具有Id-attribute.
将XML反序列化为对象,将更容易使用,并生成更清晰的代码:
模型类:
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class Model
{
private ModelPart[] partField;
[System.Xml.Serialization.XmlElementAttribute("Part")]
public ModelPart[] Part
{
get
{
return this.partField;
}
set
{
this.partField = value;
}
}
}
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ModelPart
{
private ModelPartSpecs specsField;
private byte idField;
public ModelPartSpecs Specs
{
get
{
return this.specsField;
}
set
{
this.specsField = value;
}
}
[System.Xml.Serialization.XmlAttributeAttribute()]
public byte Id
{
get
{
return this.idField;
}
set
{
this.idField = value;
}
}
}
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ModelPartSpecs
{
private ModelPartSpecsSpec specField;
public ModelPartSpecsSpec Spec
{
get
{
return this.specField;
}
set
{
this.specField = value;
}
}
}
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ModelPartSpecsSpec
{
private byte idField;
private string nameField;
[System.Xml.Serialization.XmlAttributeAttribute()]
public byte Id
{
get
{
return this.idField;
}
set
{
this.idField = value;
}
}
[System.Xml.Serialization.XmlAttributeAttribute()]
public string name
{
get
{
return this.nameField;
}
set
{
this.nameField = value;
}
}
}
反序列化:
XmlSerializer serializer = new XmlSerializer(typeof(Model));
Model model = null;
using (XmlReader reader = XmlReader.Create("data.xml"))
{
model = (Model)serializer.Deserialize(reader);
}
现在您将能够访问model
作为一个对象,访问Part
节点就像执行以下操作一样简单:
model.Part