C# 使用用户提供的排序属性值按子值对xmlElement进行排序

C# 使用用户提供的排序属性值按子值对xmlElement进行排序,c#,xml,linq-to-xml,C#,Xml,Linq To Xml,2017年6月6日03:10:02下午 错误 abc 没有一个 1. 不适用 efg 2017年6月6日上午10:13:10 错误3 o 没有一个 1. 不适用 冰河时代 2017年5月31日上午10:42:37 错误 Microsoft-Windows-CAPI2 不适用 513 不适用 访问被拒绝。。 2017年5月23日07:46:26下午 错误 微软Windows沉浸式Shell 不适用 2484 SR 你好 2017年5月23日07:46:29下午 错误 应用程序挂起 不适用 1002


2017年6月6日03:10:02下午
错误
abc
没有一个
1.
不适用
efg
2017年6月6日上午10:13:10
错误3
o
没有一个
1.
不适用
冰河时代
2017年5月31日上午10:42:37
错误
Microsoft-Windows-CAPI2
不适用
513
不适用
访问被拒绝。。
2017年5月23日07:46:26下午
错误
微软Windows沉浸式Shell
不适用
2484
SR
你好
2017年5月23日07:46:29下午
错误
应用程序挂起
不适用
1002
不适用
这里有一个错误
2017年5月23日07:45:40下午
错误
应用程序错误
应用程序崩溃事件
1000
不适用
错误号3

您确实有一个datatable,应该使用mehtod datatable.ReadXml(),但您没有发布所有真实的xml数据,因此我无法用您的输入解析xml。相反,我使用自定义XMLLINQ解析器将解析后的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();

        }

    }

}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml;
使用System.Xml.Linq;
使用系统数据;
利用制度全球化;
命名空间控制台应用程序1
{
班级计划
{
常量字符串文件名=@“c:\temp\test.xml”;
静态void Main(字符串[]参数)
{
DataTable dt=新的DataTable();
添加(“时间”,类型(日期时间));
添加(“结果”,类型(字符串));
添加(“名称”,类型(字符串));
添加(“第4列”,类型(字符串));
添加(“ID”,typeof(int));
添加(“第5列”,类型(字符串));
添加(“状态”,类型(字符串));
//2017年5月31日上午10:42:37
//错误
//Microsoft-Windows-CAPI2
//不适用
// 513
//不适用
//访问被拒绝。。
XDocument doc=XDocument.Load(文件名);
foreach(文档子体中的XElement sectionItem(“sectionItem”))
{
XElement[]单元格=sectionItem.Elements(“单元格”).ToArray();
DataRow newRow=dt.Rows.Add(新对象[]){
ParseExact((字符串)单元格[0],“dd/MM/yyyy hh:MM:ss tt”,CultureInfo.InvariantCulture),
((字符串)单元格[1]).Trim(),
((字符串)单元格[2]).Trim(),
((字符串)单元格[3]).Trim(),
(int)单元格[4],
((字符串)单元格[5]).Trim(),
((字符串)单元格[6]).Trim(),
});
}
dt=dt.AsEnumerable().OrderBy(x=>x.Field(“Name”)).CopyToDataTable();
}
}
}

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

var cells = xdoc.Element("root")
                .Elements("SectionItem")
                .Elements("Cell")
                .Where(x => x.Attribute("columnid").Value == sortCol)
                .OrderBy(x => ParseCol(sortCol, x));
这从元素“根”开始,枚举其所有子元素“SectionItem”和所有子元素“Cell”,选择与sortCol匹配的元素,然后对枚举进行排序(基于为XML字符串数据提供适当类型转换的ParseCol函数返回的类型)

我非常喜欢的DataTable方法,特别是如果您要以某种格式的网格/列表显示它

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");
        }
    }
}
使用系统;
使用System.Linq;
使用System.Xml.Linq;
名称空间解析XML{
班级计划{
静态void Main(字符串[]参数){
var xml=@”
2017年6月6日03:10:02下午
错误
abc
没有一个
1.
不适用
efg
2017年6月6日上午10:13:10
错误3
o
没有一个
1.
不适用
冰河时代
2017年5月31日上午10:42:37
错误
Microsoft-Windows-CAPI2
不适用
513
不适用
访问被拒绝。。
2017年5月23日07:46:26下午
错误
微软Windows沉浸式Shell
不适用
2484
SR
你好
2017年5月23日07:46:29下午
错误
应用程序挂起
不适用
1002
不适用
这里有一个错误
2017年5月23日07:45:40下午
错误
应用程序错误
应用程序崩溃事件
1000
不适用
错误号3
";
var sortCol=“3”;
var xdoc=XDocument.Parse(xml);
var cells=xdoc.Element(“根”)
.要素(“分项”)
.要素(“单元”)
.Where(x=>x.Attribute(“columnid”).Value==sortCol)
.OrderBy(x=>ParseCol(sortCol,x));
var newDoc=newxdocument();
变量根=新的元素(“根”);
newDoc.Add(根目录);
foreach(单元格中的var c){
root.Add(c.Parent);
}
Console.WriteLine(newDoc.ToString(SaveOptions.None));
}
静态对象ParseCol(字符串列,XElement x){
开关(col){
案例“1”:
返回long.Parse(x.Attribute(“unseconds”).Value);
案例“2”:
案例“3”:
案例“4”:
返回x.Value.Trim();
案例“5”:
返回long.Parse(x.Value);
案例“6”:
案例“7”:
返回x.Value.Trim();
违约:
抛出新ArgumentException(“坏列id字符串”);
}
}
}

}

您可能需要进行读取。听起来您可能需要使用linq获取所有SectionItem元素,然后根据columnid属性选择(子)单元格元素值并调用Sort()关于结果。不太清楚您希望从这种排序中得到什么;SectionItem属性?单元格值?总之,它看起来像是可以用相当直接的linq查询来完成的。很抱歉造成混淆。我正在尝试按排序顺序获取SectionItem元素。