【问题标题】:Using Linq to XML to parse XML file with separate metadata element使用 Linq to XML 解析具有单独元数据元素的 XML 文件
【发布时间】:2016-09-20 17:57:36
【问题描述】:

我有一个格式如下的 xml 文件,我正在尝试使用 C# Linq to 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 个 item 和相应的 value 元素,并且遵循这种格式有数百个行元素。我基本上是在寻找将元数据与值匹配的最佳方法。如果 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

【问题讨论】:

  • edit 发布并澄清以下内容:您目前这样做的方式有什么问题?您想以何种方式改进/更改现有代码?你对任务的“更好”标准是什么?

标签: c# xml linq metadata


【解决方案1】:

元素的顺序始终相同,按照它们在 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();
}

【讨论】:

    【解决方案2】:

    这是解析文件的简单方法

    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();
    
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-18
      • 2012-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多