使用User提供的sort属性值按子值对xmlElement进行排序

时间:2017-06-08 02:29:00

标签: c# xml linq-to-xml



<root>
	<SectionItem>
		 <Cell columnid="1" InSeconds="1496761802">06/06/2017  03:10:02 PM</Cell>
		 <Cell columnid="2"> Error</Cell>
		 <Cell columnid="3"> abc</Cell>
		 <Cell columnid="4">  None</Cell>
		 <Cell columnid="5">  1 </Cell>
		 <Cell columnid="6"> N/A</Cell>
		 <Cell columnid="7"> efg</Cell>
	 </SectionItem>
	 <SectionItem>
		 <Cell columnid="1" InSeconds="1496743990">06/06/2017  10:13:10 AM</Cell>
		 <Cell columnid="2"> Error</Cell>3
		 <Cell columnid="3"> o</Cell>
		 <Cell columnid="4"> None</Cell>
		 <Cell columnid="5"> 1 </Cell>
		 <Cell columnid="6">  N/A </Cell>
		 <Cell columnid="7"> ice age</Cell>
	 </SectionItem>
	 <SectionItem>
		 <Cell columnid="1" InSeconds="1496227357">31/05/2017  10:42:37 AM</Cell>
		 <Cell columnid="2"> Error</Cell>
		 <Cell columnid="3">  Microsoft-Windows-CAPI2</Cell>
		 <Cell columnid="4">  N/A</Cell>
		 <Cell columnid="5"> 513</Cell>
		 <Cell columnid="6"> N/A</Cell>
		 <Cell columnid="7">Access is denied.. </Cell>
	 </SectionItem>
	 <SectionItem>
		 <Cell columnid="1" InSeconds="1495568786">23/05/2017  07:46:26 PM</Cell>
		 <Cell columnid="2"> Error</Cell>
		 <Cell columnid="3"> Microsoft-Windows-Immersive-Shell</Cell>
		 <Cell columnid="4">  N/A</Cell>
		 <Cell columnid="5">2484</Cell>
		 <Cell columnid="6">SR</Cell>
		 <Cell columnid="7">hello</Cell>
	 </SectionItem>
	 <SectionItem>
		 <Cell columnid="1" InSeconds="1495568789">23/05/2017  07:46:29 PM</Cell>
		 <Cell columnid="2">Error</Cell>
		 <Cell columnid="3"> Application Hang </Cell>
		 <Cell columnid="4"> N/A</Cell>
		 <Cell columnid="5">1002</Cell>
		 <Cell columnid="6"> N/A</Cell>
		 <Cell columnid="7"> here is a error</Cell>
	 </SectionItem>
	 <SectionItem>
		 <Cell columnid="1" InSeconds="1495568740">23/05/2017  07:45:40 PM</Cell>
		 <Cell columnid="2"> Error</Cell>
		 <Cell columnid="3"> Application Error</Cell>
		 <Cell columnid="4"> Application Crashing Events</Cell>
		 <Cell columnid="5">1000</Cell>
		 <Cell columnid="6"> N/A</Cell>
		 <Cell columnid="7"> error number 3</Cell>
	 </SectionItem>
</root>
&#13;
&#13;
&#13;

如果我想根据用户提供的Cell属性columnID的Cell元素值对sectionItem元素进行排序,我该如何处理?提前谢谢。

e.g。如果用户给出colunid&#34; 1&#34;,那么我们希望基于Cellid =&#34; 1&#34;对Cell的值进行排序。 如果用户给出colunid&#34; 3&#34;,那么我们希望基于Cellid =&#34; 3&#34;来对基于Cell的值的sectionItem进行排序。

希望这会使问题更容易理解,因为我很难将问题放在一起。

如果我使用columnid =&#34; 3&#34;

进行排序

我应该得到以下输出:

&#13;
&#13;
<root>
	<SectionItem>
		 <Cell columnid="1" InSeconds="1496761802">06/06/2017  03:10:02 PM</Cell>
		 <Cell columnid="2"> Error</Cell>
		 <Cell columnid="3"> abc</Cell>
		 <Cell columnid="4">  None</Cell>
		 <Cell columnid="5">  1 </Cell>
		 <Cell columnid="6"> N/A</Cell>
		 <Cell columnid="7"> efg</Cell>
	 </SectionItem>
	 <SectionItem>
		 <Cell columnid="1" InSeconds="1495568740">23/05/2017  07:45:40 PM</Cell>
		 <Cell columnid="2"> Error</Cell>
		 <Cell columnid="3"> Application Error</Cell>
		 <Cell columnid="4"> Application Crashing Events</Cell>
		 <Cell columnid="5">1000</Cell>
		 <Cell columnid="6"> N/A</Cell>
		 <Cell columnid="7"> error number 3</Cell>
	 </SectionItem>
	  <SectionItem>
		 <Cell columnid="1" InSeconds="1495568789">23/05/2017  07:46:29 PM</Cell>
		 <Cell columnid="2">Error</Cell>
		 <Cell columnid="3"> Application Hang </Cell>
		 <Cell columnid="4"> N/A</Cell>
		 <Cell columnid="5">1002</Cell>
		 <Cell columnid="6"> N/A</Cell>
		 <Cell columnid="7"> here is a error</Cell>
	 </SectionItem>
	 <SectionItem>
		 <Cell columnid="1" InSeconds="1496227357">31/05/2017  10:42:37 AM</Cell>
		 <Cell columnid="2"> Error</Cell>
		 <Cell columnid="3">  Microsoft-Windows-CAPI2</Cell>
		 <Cell columnid="4">  N/A</Cell>
		 <Cell columnid="5"> 513</Cell>
		 <Cell columnid="6"> N/A</Cell>
		 <Cell columnid="7">Access is denied.. </Cell>
	 </SectionItem>
	 <SectionItem>
		 <Cell columnid="1" InSeconds="1495568786">23/05/2017  07:46:26 PM</Cell>
		 <Cell columnid="2"> Error</Cell>
		 <Cell columnid="3"> Microsoft-Windows-Immersive-Shell</Cell>
		 <Cell columnid="4">  N/A</Cell>
		 <Cell columnid="5">2484</Cell>
		 <Cell columnid="6">SR</Cell>
		 <Cell columnid="7">hello</Cell>
	 </SectionItem>
	  <SectionItem>
		 <Cell columnid="1" InSeconds="1496743990">06/06/2017  10:13:10 AM</Cell>
		 <Cell columnid="2"> Error</Cell>3
		 <Cell columnid="3"> o</Cell>
		 <Cell columnid="4"> None</Cell>
		 <Cell columnid="5"> 1 </Cell>
		 <Cell columnid="6">  N/A </Cell>
		 <Cell columnid="7"> ice age</Cell>
	 </SectionItem>
</root>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:0)

你真的有一个数据表,应该使用mehtod DataTable.ReadXml(),但你没有发布所有真正的xml数据,所以我无法用你的输入解析xml。相反,我使用自定义xml linq解析器解析了xml输入数据表。你也没有帮助你在innertex中添加额外的空格,所以我不得不修剪空间。

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


namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("Time", typeof(DateTime));
            dt.Columns.Add("Results", typeof(string));
            dt.Columns.Add("Name", typeof(string));
            dt.Columns.Add("Col 4", typeof(string));
            dt.Columns.Add("ID", typeof(int));
            dt.Columns.Add("Col 5", typeof(string));
            dt.Columns.Add("Status", typeof(string));


         //<Cell columnid="1" InSeconds="1496227357">31/05/2017  10:42:37 AM</Cell>
         //<Cell columnid="2"> Error</Cell>
         //<Cell columnid="3">  Microsoft-Windows-CAPI2</Cell>
         //<Cell columnid="4">  N/A</Cell>
         //<Cell columnid="5"> 513</Cell>
         //<Cell columnid="6"> N/A</Cell>
         //<Cell columnid="7">Access is denied.. </Cell>

            XDocument doc = XDocument.Load(FILENAME);

            foreach (XElement sectionItem in doc.Descendants("SectionItem"))
            {
                XElement[] cells = sectionItem.Elements("Cell").ToArray();
                DataRow newRow = dt.Rows.Add(new object[] {
                   DateTime.ParseExact( (string)cells[0],"dd/MM/yyyy  hh:mm:ss tt", CultureInfo.InvariantCulture),
                   ((string)cells[1]).Trim(),
                   ((string)cells[2]).Trim(),
                   ((string)cells[3]).Trim(),
                   (int)cells[4],
                   ((string)cells[5]).Trim(),
                   ((string)cells[6]).Trim(),

                });
            }

            dt = dt.AsEnumerable().OrderBy(x => x.Field<string>("Name")).CopyToDataTable();

        }

    }

}

答案 1 :(得分:0)

以下是我发表评论时的一个例子。请注意,其核心是以下linq语句:

var cells = xdoc.Element("root")
                .Elements("SectionItem")
                .Elements("Cell")
                .Where(x => x.Attribute("columnid").Value == sortCol)
                .OrderBy(x => ParseCol(sortCol, x));

从元素&#34; root&#34;开始,枚举所有它的子元素&#34; SectionItem&#34;以及他们所有的子元素&#34; Cell&#34;选择与sortCol匹配的那些,然后对枚举进行排序(基于从ParseCol函数返回的类型,该函数为您的XML字符串数据提供适当的类型转换。

我喜欢jdweng的DataTable方法,特别是如果你要以某种形式的gird / list显示它。

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

namespace ParseXml {
class Program {
    static void Main(string[] args) {

        var xml = @"
<root>
<SectionItem>
     <Cell columnid='1' InSeconds='1496761802'>06/06/2017  03:10:02 PM</Cell>
     <Cell columnid='2'> Error</Cell>
     <Cell columnid='3'> abc</Cell>
     <Cell columnid='4'>  None</Cell>
     <Cell columnid='5'>  1 </Cell>
     <Cell columnid='6'> N/A</Cell>
     <Cell columnid='7'> efg</Cell>
 </SectionItem>
 <SectionItem>
     <Cell columnid='1' InSeconds='1496743990'>06/06/2017  10:13:10 AM</Cell>
     <Cell columnid='2'> Error</Cell>3
     <Cell columnid='3'> o</Cell>
     <Cell columnid='4'> None</Cell>
     <Cell columnid='5'> 1 </Cell>
     <Cell columnid='6'>  N/A </Cell>
     <Cell columnid='7'> ice age</Cell>
 </SectionItem>
 <SectionItem>
     <Cell columnid='1' InSeconds='1496227357'>31/05/2017  10:42:37 AM</Cell>
     <Cell columnid='2'> Error</Cell>
     <Cell columnid='3'>  Microsoft-Windows-CAPI2</Cell>
     <Cell columnid='4'>  N/A</Cell>
     <Cell columnid='5'> 513</Cell>
     <Cell columnid='6'> N/A</Cell>
     <Cell columnid='7'>Access is denied.. </Cell>
 </SectionItem>
 <SectionItem>
     <Cell columnid='1' InSeconds='1495568786'>23/05/2017  07:46:26 PM</Cell>
     <Cell columnid='2'> Error</Cell>
     <Cell columnid='3'> Microsoft-Windows-Immersive-Shell</Cell>
     <Cell columnid='4'>  N/A</Cell>
     <Cell columnid='5'>2484</Cell>
     <Cell columnid='6'>SR</Cell>
     <Cell columnid='7'>hello</Cell>
 </SectionItem>
 <SectionItem>
     <Cell columnid='1' InSeconds='1495568789'>23/05/2017  07:46:29 PM</Cell>
     <Cell columnid='2'>Error</Cell>
     <Cell columnid='3'> Application Hang </Cell>
     <Cell columnid='4'> N/A</Cell>
     <Cell columnid='5'>1002</Cell>
     <Cell columnid='6'> N/A</Cell>
     <Cell columnid='7'> here is a error</Cell>
 </SectionItem>
 <SectionItem>
     <Cell columnid='1' InSeconds='1495568740'>23/05/2017  07:45:40 PM</Cell>
     <Cell columnid='2'> Error</Cell>
     <Cell columnid='3'> Application Error</Cell>
     <Cell columnid='4'> Application Crashing Events</Cell>
     <Cell columnid='5'>1000</Cell>
     <Cell columnid='6'> N/A</Cell>
     <Cell columnid='7'> error number 3</Cell>
 </SectionItem>
</root>";

    var sortCol = "3";
    var xdoc = XDocument.Parse(xml);
    var cells = xdoc.Element("root")
                    .Elements("SectionItem")
                    .Elements("Cell")
                    .Where(x => x.Attribute("columnid").Value == sortCol)
                    .OrderBy(x => ParseCol(sortCol, x));

    var newDoc = new XDocument();
    var root = new XElement("root");
    newDoc.Add(root);
    foreach (var c in cells) {
        root.Add(c.Parent);
        }

    Console.WriteLine(newDoc.ToString(SaveOptions.None));
    }

    static object ParseCol(string col, XElement x) {
        switch (col) {
        case "1":
            return long.Parse(x.Attribute("InSeconds").Value);
        case "2":
        case "3":
        case "4":
            return x.Value.Trim();
        case "5":
            return long.Parse(x.Value);
        case "6":
        case "7":
            return x.Value.Trim();
        default:
            throw new ArgumentException("Bad column id string");
        }
    }
}

}