如何处理具有层次结构的 XML 文件以获取内部细节
How to process the XML file having hierarchical structure to get the inner details
我有一个很大的 xml 文件,其中 structure.This 是一个包含许多 <xn:TestElement>
个节点的片段。
<?xml version="1.0" encoding="utf-8" ?>
<testDataFile
xmlns="http://www.3gpp.org/ftp/specs/archive/32_series/32.615#configData"
xmlns:xn="http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm" xmlns:in="http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm">
<fileHeader fileFormatVersion="32.615 V6.3" vendorName="TestVendor"/>
<configData dnPrefix="">
<xn:SubNetwork id="ONRM_ROOT_MO">
<xn:SubNetwork id="RNC425">
<xn:TestElement id="DA_Test_place0">
<xn:attributes>
<xn:userLabel>DA_Test_place0</xn:userLabel>
</xn:attributes>
<in:InventoryUnit id="n/a">
<in:attributes>
<in:manufacturerData>ProductName=Non-subrack HW,SlotCount=0</in:manufacturerData>
</in:attributes>
<in:InventoryUnit id="0">
<in:attributes>
<in:vendorUnitTypeNumber>KRC11876/1_R4A</in:vendorUnitTypeNumber>
<in:manufacturerData>ProductName=RUS 02 B8</in:manufacturerData>
</in:attributes>
</in:InventoryUnit>
<in:InventoryUnit id="0">
<in:attributes>
<in:vendorUnitTypeNumber>test/1_R4A</in:vendorUnitTypeNumber>
</in:attributes>
</in:InventoryUnit>
</in:InventoryUnit>
<in:InventoryUnit id="n/a">
<in:attributes>
<in:manufacturerData>ProductName=Virtual subrack,SlotCount=2</in:manufacturerData>
</in:attributes>
<in:InventoryUnit id="1">
<in:attributes>
<in:vendorUnitTypeNumber>KDU127174/4_R2D/A</in:vendorUnitTypeNumber>
</in:attributes>
</in:InventoryUnit>
<in:InventoryUnit id="1">
<in:attributes>
<in:vendorUnitTypeNumber>KDU127174/4_R2D/B</in:vendorUnitTypeNumber>
<in:manufacturerData>ProductName=RUS 02 B7</in:manufacturerData>
</in:attributes>
</in:InventoryUnit>
</in:InventoryUnit>
</xn:TestElement>
<xn:TestElement id="DA_Test_place1">
</xn:TestElement>
</xn:SubNetwork>
</xn:SubNetwork>
</configData>
</testDataFile>
现在我想处理这个 xml 获取如下信息:
testelementname slotdata inventory unit number
------------------------------------------------------------------------------
DA_Test_place0 ProductName=Non-subrack HW,SlotCount=0 KRC11876/1_R4A
DA_Test_place0 ProductName=Non-subrack HW,SlotCount=0 test/1_R4A
DA_Test_place0 ProductName=Virtual subrack,SlotCount=2 KDU127174/4_R2D/A
DA_Test_place0 ProductName=Virtual subrack,SlotCount=2 KDU127174/4_R2D/B
我如何处理这个 xml 文件并在数据表或 C# 类 中获取信息。我写了下面的代码,但它卡在了 xml
的层次结构中
while (reader.Read())
{
if (reader.Name != "xn:TestElement")
{
reader.ReadToFollowing("xn:TestElement");
}
while (reader.NodeType == XmlNodeType.Element && reader.LocalName == "TestElement")
{
XElement elements = (XElement)XElement.ReadFrom(reader);
testelemenname = reader.GetAttribute("id");
slotdata = GetInventoryValue(elements, "manufacturerData");
invenotry unit number = GetInventoryValue(elements, "vendorUnitTypeNumber");
}
}
private static string GetInventoryValue(XElement pin, string input)
{
XElement manufacturerData = pin.Descendants().Where(a => a.Name.LocalName == input).FirstOrDefault();
if (manufacturerData != null)
{
return (string)manufacturerData;
}
}
编辑
XML 的层次结构发生了一点变化,添加了两级“SubNetwork
”节点和一个节点“configData'and
”命名空间也发生了变化,现在我没有得到结果
您可以使用 XDocument
来达到您想要的结果。
我在这里创建了一个示例控制台应用程序以供您演示,
class Program
{
public static void Main(string[] args)
{
XDocument doc = XDocument.Load(@"Path to your xml file");
XNamespace ns = doc.Root.GetDefaultNamespace();
XNamespace xdt = "http://www.3gpp.org";
var result = doc.Descendants(ns + "TestElement")
.Elements(ns + "InventoryUnit")
.Elements(ns + "InventoryUnit")
.Select(x => new
{
test_element_name = x.AncestorsAndSelf(ns + "TestElement").FirstOrDefault()?.Attribute("id")?.Value,
slot_data = x.Ancestors(ns + "InventoryUnit").AncestorsAndSelf(ns + "InventoryUnit").FirstOrDefault().Element(ns + "attributes").Element(ns + "manufacturerData")?.Value,
invenotry_unit_number = x.Element(ns + "attributes").Element(ns + "vendorUnitTypeNumber")?.Value,
}).ToList();
//-----------Print result--------------
foreach (var item in result)
{
Console.WriteLine(item.test_element_name);
Console.WriteLine(item.slot_data);
Console.WriteLine(item.invenotry_unit_number);
Console.WriteLine();
}
Console.ReadLine();
}
}
输出:
编辑:
如果您的 xml 文件太大而 XDocument 无法解析它,那么您可以尝试 XmlSerializer
喜欢
XmlSerializer serializer = new XmlSerializer(new TestDataFile().GetType());
using (StringReader stringReader = new StringReader(File.ReadAllText(@"Path to your xml file")))
{
TestDataFile testDataFile = (TestDataFile)serializer.Deserialize(stringReader);
var result = testDataFile.ConfigData.SubNetwork.InnerSubNetwork.SelectMany(a => a.TestElement.SelectMany(x => x.InventoryUnit.SelectMany(y => y.IU
.Select(z => new { test_element_name = x.Id, slot_data = y.Attributes.ManufacturerData, invenotry_unit_number = z.Attributes.VendorUnitTypeNumber })))).ToList();
foreach (var item in result)
{
Console.WriteLine(item.test_element_name);
Console.WriteLine(item.slot_data);
Console.WriteLine(item.invenotry_unit_number);
Console.WriteLine();
}
}
并且您需要在 class 层次结构下反序列化您的 xml、
[XmlRoot(ElementName = "fileHeader", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public class FileHeader
{
[XmlAttribute(AttributeName = "fileFormatVersion")]
public string FileFormatVersion { get; set; }
[XmlAttribute(AttributeName = "vendorName")]
public string VendorName { get; set; }
}
[XmlRoot(ElementName = "attributes", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public class Attributes
{
[XmlElement(ElementName = "userLabel", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public string UserLabel { get; set; }
[XmlElement(ElementName = "manufacturerData", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public string ManufacturerData { get; set; }
[XmlElement(ElementName = "vendorUnitTypeNumber", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public string VendorUnitTypeNumber { get; set; }
}
[XmlRoot(ElementName = "InventoryUnit", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public class InnerInventoryUnit
{
[XmlElement(ElementName = "attributes", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public Attributes Attributes { get; set; }
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
}
[XmlRoot(ElementName = "InventoryUnit", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public class InventoryUnit
{
[XmlElement(ElementName = "attributes", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public Attributes Attributes { get; set; }
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
[XmlElement(ElementName = "InventoryUnit", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public List<InnerInventoryUnit> IU { get; set; }
}
[XmlRoot(ElementName = "TestElement", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm")]
public class TestElement
{
[XmlElement(ElementName = "InventoryUnit", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public List<InventoryUnit> InventoryUnit { get; set; }
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
}
[XmlRoot(ElementName = "SubNetwork", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm")]
public class InnerSubNetwork
{
[XmlElement(ElementName = "TestElement", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm")]
public List<TestElement> TestElement { get; set; }
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
}
[XmlRoot(ElementName = "SubNetwork", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm")]
public class SubNetwork
{
[XmlElement(ElementName = "SubNetwork", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm")]
public List<InnerSubNetwork> InnerSubNetwork { get; set; }
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
}
[XmlRoot(ElementName = "configData", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.615#configData")]
public class ConfigData
{
[XmlElement(ElementName = "SubNetwork", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm")]
public SubNetwork SubNetwork { get; set; }
[XmlAttribute(AttributeName = "dnPrefix")]
public string DnPrefix { get; set; }
}
[XmlRoot(ElementName = "testDataFile", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.615#configData")]
public class TestDataFile
{
[XmlElement(ElementName = "fileHeader", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.615#configData")]
public FileHeader FileHeader { get; set; }
[XmlElement(ElementName = "configData", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.615#configData")]
public ConfigData ConfigData { get; set; }
[XmlAttribute(AttributeName = "xmlns")]
public string Xmlns { get; set; }
[XmlAttribute(AttributeName = "xn", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Xn { get; set; }
[XmlAttribute(AttributeName = "in", Namespace = "http://www.w3.org/2000/xmlns/")]
public string In { get; set; }
}
我有一个很大的 xml 文件,其中 structure.This 是一个包含许多 <xn:TestElement>
个节点的片段。
<?xml version="1.0" encoding="utf-8" ?>
<testDataFile
xmlns="http://www.3gpp.org/ftp/specs/archive/32_series/32.615#configData"
xmlns:xn="http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm" xmlns:in="http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm">
<fileHeader fileFormatVersion="32.615 V6.3" vendorName="TestVendor"/>
<configData dnPrefix="">
<xn:SubNetwork id="ONRM_ROOT_MO">
<xn:SubNetwork id="RNC425">
<xn:TestElement id="DA_Test_place0">
<xn:attributes>
<xn:userLabel>DA_Test_place0</xn:userLabel>
</xn:attributes>
<in:InventoryUnit id="n/a">
<in:attributes>
<in:manufacturerData>ProductName=Non-subrack HW,SlotCount=0</in:manufacturerData>
</in:attributes>
<in:InventoryUnit id="0">
<in:attributes>
<in:vendorUnitTypeNumber>KRC11876/1_R4A</in:vendorUnitTypeNumber>
<in:manufacturerData>ProductName=RUS 02 B8</in:manufacturerData>
</in:attributes>
</in:InventoryUnit>
<in:InventoryUnit id="0">
<in:attributes>
<in:vendorUnitTypeNumber>test/1_R4A</in:vendorUnitTypeNumber>
</in:attributes>
</in:InventoryUnit>
</in:InventoryUnit>
<in:InventoryUnit id="n/a">
<in:attributes>
<in:manufacturerData>ProductName=Virtual subrack,SlotCount=2</in:manufacturerData>
</in:attributes>
<in:InventoryUnit id="1">
<in:attributes>
<in:vendorUnitTypeNumber>KDU127174/4_R2D/A</in:vendorUnitTypeNumber>
</in:attributes>
</in:InventoryUnit>
<in:InventoryUnit id="1">
<in:attributes>
<in:vendorUnitTypeNumber>KDU127174/4_R2D/B</in:vendorUnitTypeNumber>
<in:manufacturerData>ProductName=RUS 02 B7</in:manufacturerData>
</in:attributes>
</in:InventoryUnit>
</in:InventoryUnit>
</xn:TestElement>
<xn:TestElement id="DA_Test_place1">
</xn:TestElement>
</xn:SubNetwork>
</xn:SubNetwork>
</configData>
</testDataFile>
现在我想处理这个 xml 获取如下信息:
testelementname slotdata inventory unit number
------------------------------------------------------------------------------
DA_Test_place0 ProductName=Non-subrack HW,SlotCount=0 KRC11876/1_R4A
DA_Test_place0 ProductName=Non-subrack HW,SlotCount=0 test/1_R4A
DA_Test_place0 ProductName=Virtual subrack,SlotCount=2 KDU127174/4_R2D/A
DA_Test_place0 ProductName=Virtual subrack,SlotCount=2 KDU127174/4_R2D/B
我如何处理这个 xml 文件并在数据表或 C# 类 中获取信息。我写了下面的代码,但它卡在了 xml
的层次结构中while (reader.Read())
{
if (reader.Name != "xn:TestElement")
{
reader.ReadToFollowing("xn:TestElement");
}
while (reader.NodeType == XmlNodeType.Element && reader.LocalName == "TestElement")
{
XElement elements = (XElement)XElement.ReadFrom(reader);
testelemenname = reader.GetAttribute("id");
slotdata = GetInventoryValue(elements, "manufacturerData");
invenotry unit number = GetInventoryValue(elements, "vendorUnitTypeNumber");
}
}
private static string GetInventoryValue(XElement pin, string input)
{
XElement manufacturerData = pin.Descendants().Where(a => a.Name.LocalName == input).FirstOrDefault();
if (manufacturerData != null)
{
return (string)manufacturerData;
}
}
编辑
XML 的层次结构发生了一点变化,添加了两级“SubNetwork
”节点和一个节点“configData'and
”命名空间也发生了变化,现在我没有得到结果
您可以使用 XDocument
来达到您想要的结果。
我在这里创建了一个示例控制台应用程序以供您演示,
class Program
{
public static void Main(string[] args)
{
XDocument doc = XDocument.Load(@"Path to your xml file");
XNamespace ns = doc.Root.GetDefaultNamespace();
XNamespace xdt = "http://www.3gpp.org";
var result = doc.Descendants(ns + "TestElement")
.Elements(ns + "InventoryUnit")
.Elements(ns + "InventoryUnit")
.Select(x => new
{
test_element_name = x.AncestorsAndSelf(ns + "TestElement").FirstOrDefault()?.Attribute("id")?.Value,
slot_data = x.Ancestors(ns + "InventoryUnit").AncestorsAndSelf(ns + "InventoryUnit").FirstOrDefault().Element(ns + "attributes").Element(ns + "manufacturerData")?.Value,
invenotry_unit_number = x.Element(ns + "attributes").Element(ns + "vendorUnitTypeNumber")?.Value,
}).ToList();
//-----------Print result--------------
foreach (var item in result)
{
Console.WriteLine(item.test_element_name);
Console.WriteLine(item.slot_data);
Console.WriteLine(item.invenotry_unit_number);
Console.WriteLine();
}
Console.ReadLine();
}
}
输出:
编辑:
如果您的 xml 文件太大而 XDocument 无法解析它,那么您可以尝试 XmlSerializer
喜欢
XmlSerializer serializer = new XmlSerializer(new TestDataFile().GetType());
using (StringReader stringReader = new StringReader(File.ReadAllText(@"Path to your xml file")))
{
TestDataFile testDataFile = (TestDataFile)serializer.Deserialize(stringReader);
var result = testDataFile.ConfigData.SubNetwork.InnerSubNetwork.SelectMany(a => a.TestElement.SelectMany(x => x.InventoryUnit.SelectMany(y => y.IU
.Select(z => new { test_element_name = x.Id, slot_data = y.Attributes.ManufacturerData, invenotry_unit_number = z.Attributes.VendorUnitTypeNumber })))).ToList();
foreach (var item in result)
{
Console.WriteLine(item.test_element_name);
Console.WriteLine(item.slot_data);
Console.WriteLine(item.invenotry_unit_number);
Console.WriteLine();
}
}
并且您需要在 class 层次结构下反序列化您的 xml、
[XmlRoot(ElementName = "fileHeader", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public class FileHeader
{
[XmlAttribute(AttributeName = "fileFormatVersion")]
public string FileFormatVersion { get; set; }
[XmlAttribute(AttributeName = "vendorName")]
public string VendorName { get; set; }
}
[XmlRoot(ElementName = "attributes", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public class Attributes
{
[XmlElement(ElementName = "userLabel", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public string UserLabel { get; set; }
[XmlElement(ElementName = "manufacturerData", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public string ManufacturerData { get; set; }
[XmlElement(ElementName = "vendorUnitTypeNumber", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public string VendorUnitTypeNumber { get; set; }
}
[XmlRoot(ElementName = "InventoryUnit", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public class InnerInventoryUnit
{
[XmlElement(ElementName = "attributes", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public Attributes Attributes { get; set; }
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
}
[XmlRoot(ElementName = "InventoryUnit", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public class InventoryUnit
{
[XmlElement(ElementName = "attributes", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public Attributes Attributes { get; set; }
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
[XmlElement(ElementName = "InventoryUnit", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public List<InnerInventoryUnit> IU { get; set; }
}
[XmlRoot(ElementName = "TestElement", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm")]
public class TestElement
{
[XmlElement(ElementName = "InventoryUnit", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.695#inventoryNrm")]
public List<InventoryUnit> InventoryUnit { get; set; }
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
}
[XmlRoot(ElementName = "SubNetwork", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm")]
public class InnerSubNetwork
{
[XmlElement(ElementName = "TestElement", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm")]
public List<TestElement> TestElement { get; set; }
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
}
[XmlRoot(ElementName = "SubNetwork", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm")]
public class SubNetwork
{
[XmlElement(ElementName = "SubNetwork", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm")]
public List<InnerSubNetwork> InnerSubNetwork { get; set; }
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
}
[XmlRoot(ElementName = "configData", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.615#configData")]
public class ConfigData
{
[XmlElement(ElementName = "SubNetwork", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm")]
public SubNetwork SubNetwork { get; set; }
[XmlAttribute(AttributeName = "dnPrefix")]
public string DnPrefix { get; set; }
}
[XmlRoot(ElementName = "testDataFile", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.615#configData")]
public class TestDataFile
{
[XmlElement(ElementName = "fileHeader", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.615#configData")]
public FileHeader FileHeader { get; set; }
[XmlElement(ElementName = "configData", Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.615#configData")]
public ConfigData ConfigData { get; set; }
[XmlAttribute(AttributeName = "xmlns")]
public string Xmlns { get; set; }
[XmlAttribute(AttributeName = "xn", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Xn { get; set; }
[XmlAttribute(AttributeName = "in", Namespace = "http://www.w3.org/2000/xmlns/")]
public string In { get; set; }
}