【问题标题】:Sort file by Element value [duplicate]按元素值排序文件[重复]
【发布时间】:2015-02-06 19:45:53
【问题描述】:

我有以下 xml 文件。(示例).. 我需要按属性“InvcDate”对“发票”节点进行排序。这在Linq中甚至可能吗?任何帮助将不胜感激。

我已经尝试了一段时间,但是我对 xml 没有太多经验,并且是编程的新手,所以我非常感谢任何帮助。

<?xml version="1.0" encoding="utf-8"?>
<Server>
  <Name>AlignServer</Name>
  <Params>
<marketNo>MT</marketNo>
    <dateFrom>2015-01-06</dateFrom>
    <dateTo>2015-01-09</dateTo>
    <Sales>
      <invoices>
        <invoice>
          <header>
            <InvoiceNum>22947</InvoiceNum>
            <InvcDate>2015/01/07-110104</InvcDate>
          </header>
          <item>
            <SKU>6595456987453</SKU>
            <Qty>-1</Qty>
          </item>
        </invoice>
        <invoice>
          <header>
            <InvoiceNum>23056</InvoiceNum>
            <InvcDate>2015/01/08-020627</InvcDate>
          </header>
          <item>
            <SKU>9845256242255</SKU>
            <Qty>-1</Qty>
          </item>
        </invoice>
        <invoice>
          <header>
            <InvoiceNum>22899</InvoiceNum>
            <InvcDate>2015/01/06-094505</InvcDate>
          </header>
          <item>
            <SKU>5454256565452</SKU>
            <Qty>-1</Qty>
          </item>
          <item>
            <SKU>11111165454130</SKU>
            <Qty>4</Qty>
          </item>
        </invoice>
      </invoices>
    </Sales>
  </Params>
</Server>

我试过了

XElement root = XElement.Load("C:\\xmlsort\\test.xml");
XElement[] sortedTables = root.Elements("invoices").OrderBy(t =>   (Datetime)t.Element("invdate")).ToArray();
root.ReplaceAll(sortedTables);
root.Save("C:\\xmlsort\\test.xml");

到目前为止我所做的 - 来自 @ec8or 的建议,似乎有效,但仍然愿意接受建议:

XElement root = XElement.Load("C:\\xmlsort\\test.xml");
var invoices = from p in root.Descendants("invoice")
                       orderby DateTime.ParseExact(p.Element("header").Element("InvcDate").Value, "yyyy/MM/dd-hhmmss", CultureInfo.InvariantCulture)
select p;
XElement[] sortedTables = invoices.ToArray();

root.ReplaceAll(sortedTables);
root.Save("C:\\xmlsort\\output.xml");

【问题讨论】:

  • 你尝试过什么吗? - 给我们看
  • XElement root = XElement.Load("C:\\xmlsort\\test.xml"); XElement[] sortedTables = root.Elements("invoices").OrderBy(t => (datetime)t.Element("invoice/InvcDate")).ToArray(); root.ReplaceAll(sortedTables); root.Save("C:\\xmlsort\\test.xml");

标签: c# xml linq sorting


【解决方案1】:

在 XElement 中阅读 XML:

XElement element = XElement.Load("doc.xml");

查询你的 XML 数据:

var invoices = from p in element.Descendants ("invoice")
               orderby DateTime.ParseExact(p.Element("header").Element("InvcDate").Value, "yyyy/MM/dd-hhmmss", CultureInfo.InvariantCulture)
               select p;

打印到控制台:

foreach (var invoice in invoices) {
    Console.WriteLine (invoice.ToString ());
}

编辑 在 cmets 中回答您的问题。

XDocument doc = XDocument.Load ("data.xml");

选择所有父节点:

var baseElement = doc.XPathSelectElement ("/Server/Params/Sales/invoices");

对内部节点进行排序:

var sortedElements = baseElement.Elements ()
    .OrderBy (e => (DateTime)e.XPathSelectElement("header/InvoiceNum"))
    .ToList (); 

用排序内容替换当前内容:

baseElement.ReplaceAll (sortedElements);
doc.Save ("out.xml");

【讨论】:

  • 为什么不用XElement.Load("doc.xml") 而不是XElement.Parse (File.ReadAllText("doc.xml"))
  • XElement root = XElement.Load("C:\\xmlsort\\test.xml"); var invoices = from p in root.Descendants("invoice") orderby DateTime.ParseExact(p.Element("header").Element("InvcDate").Value, "yyyy/MM/dd-hhmmss", CultureInfo.InvariantCulture ) 选择 p; XElement[] sortedTables = invoices.ToArray(); root.ReplaceAll(sortedTables); root.Save("C:\\xmlsort\\output.xml");
  • @PetSerAl 你是对的。
  • @MaltaBd 这是您的解决方案还是一个问题?如果我的回答对您有所帮助,请将其标记为答案。 :)
  • @ec8or - 我刚刚意识到,我使用的代码删除了以前的节点 - "AlignServerMT2015-01 -062015-01-09 - 我该如何解决这个问题?
猜你喜欢
  • 1970-01-01
  • 2018-03-26
  • 1970-01-01
  • 2019-04-07
  • 1970-01-01
  • 2016-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多