为c#应用程序建模XML数据。

时间:2022-03-19 17:09:31

I'm missing a concept with regards to modeling data in XML. Consider the following XML which is going to hold some configuration data for an application I'm writing.

关于用XML建模数据,我缺少一个概念。考虑下面的XML,它将为我正在编写的应用程序保存一些配置数据。

 <?xml version="1.0" encoding="utf-8"?>
<DateGuessConfigValues>
  <Players>
    <Player Id="1">
      <Name>Yusnier Viera</Name>
      <Country>Cuba</Country>
    </Player>
    <Player Id="2">
      <Name>Ron White</Name>
      <Country>USA</Country>
    </Player>    
  </Players>
  <Centuries>
    <Century>1900</Century>
    <Century>2000</Century>
  </Centuries>
</DateGuessConfigValues>

I'm storing this XML in a file named "DateGuessConfig.xml" and then running the following program...

我将这个XML存储在一个名为“DateGuessConfig”的文件中。然后运行以下程序……

using System;
using System.Xml.Linq;
using System.Linq;

class Program
{
    public static void Main(String[] args)
    {
        String strPath = @"C:\XMLExample\DateGuessConfig.xml";
        XElement xEle = XElement.Load(strPath);    
        var query = xEle.Descendants("Centuries").ToList();    
        foreach (var c in query)
        {
            Console.WriteLine(c.Element("Century").Value);
        }
        Console.WriteLine("Press <enter> to continue");
        Console.ReadLine();
    }
}

I expect my result to be...

我希望我的结果是……

1900

1900年

2000

2000年

However I'm only getting

但是我只得到

1900

1900年

Am I modeling the data incorrectly? should I use an attribute instead of inner text?

我对数据的建模是否错误?我应该使用属性而不是内部文本吗?

3 个解决方案

#1


1  

This can be simplified to just use the Descendants call:

这可以简化为使用后代调用:

foreach (var c in xEle.Descendants("Century"))
{
   Console.WriteLine(c.Value);
}

This is slightly different than MikeH's answer which still runs the query

这与仍然运行查询的MikeH的答案稍有不同

#2


2  

query in your example has only one element: The Centuries node. You need to access its descendants. So, in your example it went through the loop once and retrieved the first Century value.

在您的示例中查询只有一个元素:世纪节点。您需要访问它的后代。所以,在你的例子中,它经历了一次循环并取回了第一世纪的价值。

Try replacing your foreach with this:

试着把你的foreach换成这个:

 foreach (var c in query.Descendants("Century"))
      {
        Console.WriteLine(c.Value);
      }

#3


1  

You may want to use a DataTable instead. See code below. It will write with schema so integers don't have to be parsed.

您可能需要使用一个DataTable代替。请参见下面的代码。它将使用模式编写,因此不必解析整数。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;


namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            DataSet ds = new DataSet("DateGuessConfigValues");
            DataTable playerTable = new DataTable("Players");
            ds.Tables.Add(playerTable);
            DataTable centuriesTable = new DataTable("Centuries");
            ds.Tables.Add(centuriesTable);

            playerTable.Columns.Add("Id", typeof(int));
            playerTable.Columns.Add("Name", typeof(string));
            playerTable.Columns.Add("Country", typeof(string));

            playerTable.Rows.Add(new object[] {1, "Viera", "Cuba"});
            playerTable.Rows.Add(new object[] {2, "Ron White", "USA"});


            centuriesTable.Columns.Add("Century", typeof(int));

            centuriesTable.Rows.Add(new object[] { 1900});
            centuriesTable.Rows.Add(new object[] { 2000});

            ds.WriteXml("Filename", XmlWriteMode.WriteSchema);

            ds = new DataSet();
            ds.ReadXml("Filename");
        }
    }


}

​

#1


1  

This can be simplified to just use the Descendants call:

这可以简化为使用后代调用:

foreach (var c in xEle.Descendants("Century"))
{
   Console.WriteLine(c.Value);
}

This is slightly different than MikeH's answer which still runs the query

这与仍然运行查询的MikeH的答案稍有不同

#2


2  

query in your example has only one element: The Centuries node. You need to access its descendants. So, in your example it went through the loop once and retrieved the first Century value.

在您的示例中查询只有一个元素:世纪节点。您需要访问它的后代。所以,在你的例子中,它经历了一次循环并取回了第一世纪的价值。

Try replacing your foreach with this:

试着把你的foreach换成这个:

 foreach (var c in query.Descendants("Century"))
      {
        Console.WriteLine(c.Value);
      }

#3


1  

You may want to use a DataTable instead. See code below. It will write with schema so integers don't have to be parsed.

您可能需要使用一个DataTable代替。请参见下面的代码。它将使用模式编写,因此不必解析整数。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;


namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            DataSet ds = new DataSet("DateGuessConfigValues");
            DataTable playerTable = new DataTable("Players");
            ds.Tables.Add(playerTable);
            DataTable centuriesTable = new DataTable("Centuries");
            ds.Tables.Add(centuriesTable);

            playerTable.Columns.Add("Id", typeof(int));
            playerTable.Columns.Add("Name", typeof(string));
            playerTable.Columns.Add("Country", typeof(string));

            playerTable.Rows.Add(new object[] {1, "Viera", "Cuba"});
            playerTable.Rows.Add(new object[] {2, "Ron White", "USA"});


            centuriesTable.Columns.Add("Century", typeof(int));

            centuriesTable.Rows.Add(new object[] { 1900});
            centuriesTable.Rows.Add(new object[] { 2000});

            ds.WriteXml("Filename", XmlWriteMode.WriteSchema);

            ds = new DataSet();
            ds.ReadXml("Filename");
        }
    }


}

​