使用Linq to XML解析具有单独元数据元素的XML文件
本文关键字:XML 元数据 单独 元素 文件 Linq to 使用 | 更新日期: 2023-09-27 18:08:09
我有一个具有以下格式的xml文件,我试图用c# Linq解析xml。问题是它有这个单独的元数据元素,它是标识下面值的唯一元素。有什么好办法吗?我无权更改这个文件的格式。
<?xml version="1.0" encoding="utf-8?>
<dataset xmlns="http://developer.cognos.com/schemas/xmldata/1/" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
<metadata>
<item name="Address Line 1" type="xs:string" length="512"/>
<item name="Address Line 2" type="xs:string" length="512"/>
<item name="Date Of Birth" type="xs:dateTime"/>
</metadata>
<data>
<row>
<value>123 Main St</value>
<value xs:nil="true" />
<value>1970-01-01T00:00:00</value>
</row>
<row>
<value>125 Main St</value>
<value>Apt 1</value>
<value>1980-01-01T00:00:00</value>
</row>
</data>
</dataset>
实际的文件在每行中大约有30个项目和相应的值元素,以及遵循这种格式的数百个行元素。我基本上是在寻找将元数据与值匹配的最佳方法。如果Linq to XML不是实现这一目标的最佳方式,我愿意接受其他与c#和。net 4.5一起工作的建议。
我尝试只是收集一个列表中的元数据项目,并使用索引将它们与值匹配,但它似乎以任意顺序构建列表,所以我不确定我可以依靠该顺序来识别值。
XDocument xdoc = XDocument.Load(@"Export.xml");
XNamespace xns = "http://developer.cognos.com/schemas/xmldata/1/";
var metadataQuery = from t in xdoc.Descendants(xns + "item") select t;
List<XElement> metadata = metadataQuery.ToList(); // This list appears to be ordered randomly
元素的顺序始终是相同的,按照它们在xml文件中出现的顺序。
var xdoc = XDocument.Load(@"Export.xml");
XNamespace xns = "http://developer.cognos.com/schemas/xmldata/1/";
var metadata = xdoc.Descendants(xns + "item").ToList();
var data = xdoc.Descendants(xns + "row").ToList();
foreach (var datum in data)
{
var values = datum.Elements(xns + "value").ToList();
for (int i = 0; i < values.Count; i++)
{
Console.WriteLine(metadata[i].Attribute("name").Value + ": " + values[i].Value);
}
Console.WriteLine();
}
下面是解析文件
的简单方法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);
XElement dataset = (XElement)doc.FirstNode;
XNamespace ns = dataset.Name.Namespace;
var results = doc.Descendants(ns + "row").Select(x => new {
firstAddr = (string)x.Elements(ns + "value").FirstOrDefault(),
secondAddr = (string)x.Elements(ns + "value").Skip(1).FirstOrDefault(),
dob = (DateTime)x.Elements(ns + "value").Skip(2).FirstOrDefault()
}).ToList();
}
}
}