按 XDocument 类型获取元素
Get element by type XDocument
如何使用 XDocument 找到以下结构的正确元素?
XML:
<Body xmlns="http://tempuri.org/body" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Address>
<Segment i:type="AddressSegment">
<Id>9999</Id>
</Segment>
</Address>
<Segmentation>
<Segment xmlns:d4p1="http://tempuri.org/foo" i:type="d4p1:FooSegment">
<d4p1:Id>63</d4p1:Id>
</Segment>
<Segment xmlns:d4p1="http://tempuri.org/bar" i:type="d4p1:BarSegment">
<d4p1:Id>159</d4p1:Id>
</Segment>
<Segment i:type="BasicSegment">
<Id>10</Id>
</Segment>
</Segmentation>
</Body>
C#:
using ConsoleApp1.Properties;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var xDoc = XDocument.Parse(Resources.XmlDoc);
var dataSegments = xDoc.Descendants(XName.Get("Segment", "http://tempuri.org/body")).ToList();
Console.ReadLine();
}
}
}
这将导致我列表中的所有 Segment 元素。但是如果我只想 select Foo 和 Bar 元素怎么办?怎么可能找到 i:type 个元素?
输入XML。更正了命名空间..
<?xml version="1.0" encoding="utf-8" ?>
<Body xmlns:i="http://tempuri.org/body">
<Address>
<Segment i:type="AddressSegment">
<Id>9999</Id>
</Segment>
</Address>
<Segmentation>
<Segment xmlns:d4p1="http://tempuri.org/foo" i:type="d4p1:FooSegment">
<d4p1:Id>63</d4p1:Id>
</Segment>
<Segment xmlns:d4p1="http://tempuri.org/bar" i:type="d4p1:BarSegment">
<d4p1:Id>159</d4p1:Id>
</Segment>
<Segment i:type="BasicSegment">
<Id>10</Id>
</Segment>
</Segmentation>
</Body>
使用 xmltocsharp
为 FooSegment 和 BooSegment 创建模型 class
[XmlRoot(ElementName = "Segment")]
public class FooSegment
{
[XmlElement(ElementName = "Id", Namespace = "http://tempuri.org/foo")]
public List<string> Id { get; set; }
[XmlAttribute(AttributeName = "d4p1", Namespace = "http://www.w3.org/2000/xmlns/")]
public string D4p1 { get; set; }
[XmlAttribute(AttributeName = "type", Namespace = "http://tempuri.org/body")]
public string Type { get; set; }
}
[XmlRoot(ElementName = "Segment")]
public class BarSegment
{
[XmlElement(ElementName = "Id", Namespace = "http://tempuri.org/bar")]
public List<string> Id { get; set; }
[XmlAttribute(AttributeName = "d4p1", Namespace = "http://www.w3.org/2000/xmlns/")]
public string D4p1 { get; set; }
[XmlAttribute(AttributeName = "type", Namespace = "http://tempuri.org/body")]
public string Type { get; set; }
}
使用此模型使用 XmlSerializer 进行反序列化
XDocument xml = XDocument.Load("1.xml");
XNamespace ns = "http://tempuri.org/body";
string[] values = new string[] { "d4p1:FooSegment", "d4p1:BarSegment" };
var result = xml.Root.DescendantsAndSelf("Segment")
.Where(r => values.Contains((string)r.Attribute(ns + "type").Value));
foreach (var nodeValue in result)
{
if(nodeValue.Attribute(ns + "type").Value.ToString() == "d4p1:FooSegment")
{
var fooObject = (FooSegment)new XmlSerializer(typeof(FooSegment)).Deserialize(new StringReader(nodeValue.ToString()));
Console.WriteLine($"{fooObject.Id[0]}");
}
else
{
var barObject = (BarSegment)new XmlSerializer(typeof(BarSegment)).Deserialize(new StringReader(nodeValue.ToString()));
Console.WriteLine($"{barObject.Id[0]}");
}
}
输出
63
159
如何使用 XDocument 找到以下结构的正确元素?
XML:
<Body xmlns="http://tempuri.org/body" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Address>
<Segment i:type="AddressSegment">
<Id>9999</Id>
</Segment>
</Address>
<Segmentation>
<Segment xmlns:d4p1="http://tempuri.org/foo" i:type="d4p1:FooSegment">
<d4p1:Id>63</d4p1:Id>
</Segment>
<Segment xmlns:d4p1="http://tempuri.org/bar" i:type="d4p1:BarSegment">
<d4p1:Id>159</d4p1:Id>
</Segment>
<Segment i:type="BasicSegment">
<Id>10</Id>
</Segment>
</Segmentation>
</Body>
C#:
using ConsoleApp1.Properties;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var xDoc = XDocument.Parse(Resources.XmlDoc);
var dataSegments = xDoc.Descendants(XName.Get("Segment", "http://tempuri.org/body")).ToList();
Console.ReadLine();
}
}
}
这将导致我列表中的所有 Segment 元素。但是如果我只想 select Foo 和 Bar 元素怎么办?怎么可能找到 i:type 个元素?
输入XML。更正了命名空间..
<?xml version="1.0" encoding="utf-8" ?>
<Body xmlns:i="http://tempuri.org/body">
<Address>
<Segment i:type="AddressSegment">
<Id>9999</Id>
</Segment>
</Address>
<Segmentation>
<Segment xmlns:d4p1="http://tempuri.org/foo" i:type="d4p1:FooSegment">
<d4p1:Id>63</d4p1:Id>
</Segment>
<Segment xmlns:d4p1="http://tempuri.org/bar" i:type="d4p1:BarSegment">
<d4p1:Id>159</d4p1:Id>
</Segment>
<Segment i:type="BasicSegment">
<Id>10</Id>
</Segment>
</Segmentation>
</Body>
使用 xmltocsharp
为 FooSegment 和 BooSegment 创建模型 class[XmlRoot(ElementName = "Segment")]
public class FooSegment
{
[XmlElement(ElementName = "Id", Namespace = "http://tempuri.org/foo")]
public List<string> Id { get; set; }
[XmlAttribute(AttributeName = "d4p1", Namespace = "http://www.w3.org/2000/xmlns/")]
public string D4p1 { get; set; }
[XmlAttribute(AttributeName = "type", Namespace = "http://tempuri.org/body")]
public string Type { get; set; }
}
[XmlRoot(ElementName = "Segment")]
public class BarSegment
{
[XmlElement(ElementName = "Id", Namespace = "http://tempuri.org/bar")]
public List<string> Id { get; set; }
[XmlAttribute(AttributeName = "d4p1", Namespace = "http://www.w3.org/2000/xmlns/")]
public string D4p1 { get; set; }
[XmlAttribute(AttributeName = "type", Namespace = "http://tempuri.org/body")]
public string Type { get; set; }
}
使用此模型使用 XmlSerializer 进行反序列化
XDocument xml = XDocument.Load("1.xml");
XNamespace ns = "http://tempuri.org/body";
string[] values = new string[] { "d4p1:FooSegment", "d4p1:BarSegment" };
var result = xml.Root.DescendantsAndSelf("Segment")
.Where(r => values.Contains((string)r.Attribute(ns + "type").Value));
foreach (var nodeValue in result)
{
if(nodeValue.Attribute(ns + "type").Value.ToString() == "d4p1:FooSegment")
{
var fooObject = (FooSegment)new XmlSerializer(typeof(FooSegment)).Deserialize(new StringReader(nodeValue.ToString()));
Console.WriteLine($"{fooObject.Id[0]}");
}
else
{
var barObject = (BarSegment)new XmlSerializer(typeof(BarSegment)).Deserialize(new StringReader(nodeValue.ToString()));
Console.WriteLine($"{barObject.Id[0]}");
}
}
输出
63
159