如何针对节点内的两个或三个元素对xml文档进行排序

时间:2017-06-13 11:32:55

标签: c# xml

如何针对特定节点内的一个或多个元素对整个XML文档进行排序,并将其存储为新的XML文件。 对于前 - “输入文件”

<?xml version="1.0" encoding="utf-8"?>
<ABCD>
    <XYZ>
      <LEVEL>0</LEVEL>
      <ITEM>331-4437</ITEM>
      <QTY>1</QTY>
      <REV>A02-00</REV>
      <STATUS>B</STATUS>
      <ITEM_MOST_ACTIVE_STATUS>B</ITEM_MOST_ACTIVE_STATUS>
        <XYZ>
            <LEVEL>1</LEVEL>
            <PARENT_ITEM>331-4437</PARENT_ITEM>
            <ITEM>1234</ITEM>
            <QTY>1</QTY>
            <REV>A02-00</REV>
            <STATUS>B</STATUS>
            <ITEM_MOST_ACTIVE_STATUS>B</ITEM_MOST_ACTIVE_STATUS>
        </XYZ>
        <XYZ>
            <LEVEL>1</LEVEL>
            <PARENT_ITEM>331-4437</PARENT_ITEM>
            <ITEM>0234</ITEM>
            <QTY>1</QTY>
            <REV>A02-00</REV>
            <STATUS>B</STATUS>
            <ITEM_MOST_ACTIVE_STATUS>B</ITEM_MOST_ACTIVE_STATUS>
            <SOMETHING>fgh</SOMETHING>
        </XYZ>
    </XYZ>
    <XYZ>
      <LEVEL>0</LEVEL>
      <ITEM>2240123</ITEM>
      <QTY>1</QTY>
      <REV>A02-00</REV>
      <STATUS>B</STATUS>
      <ITEM_MOST_ACTIVE_STATUS>B</ITEM_MOST_ACTIVE_STATUS>
      <SOMETHING>fgh</SOMETHING>
    </XYZ>
</ABCD>

如何根据级别&amp; item&amp; parent项目(如果存在)对xml进行排序。我是C#的新手,所以请帮我一些代码。 “输出应该看起来像”

<?xml version="1.0" encoding="utf-8"?>
<ABCD>
   <XYZ>
      <LEVEL>0</LEVEL>
      <ITEM>2240123</ITEM>
      <QTY>1</QTY>
      <REV>A02-00</REV>
      <STATUS>B</STATUS>
      <ITEM_MOST_ACTIVE_STATUS>B</ITEM_MOST_ACTIVE_STATUS>
      <SOMETHING>fgh</SOMETHING>
    </XYZ>
    <XYZ>
      <LEVEL>0</LEVEL>
      <ITEM>331-4437</ITEM>
      <QTY>1</QTY>
      <REV>A02-00</REV>
      <STATUS>B</STATUS>
      <ITEM_MOST_ACTIVE_STATUS>B</ITEM_MOST_ACTIVE_STATUS>
      <XYZ>
            <LEVEL>1</LEVEL>
            <PARENT_ITEM>331-4437</PARENT_ITEM>
            <ITEM>0234</ITEM>
            <QTY>1</QTY>
            <REV>A02-00</REV>
            <STATUS>B</STATUS>
            <ITEM_MOST_ACTIVE_STATUS>B</ITEM_MOST_ACTIVE_STATUS>
            <SOMETHING>fgh</SOMETHING>
        </XYZ>
        <XYZ>
            <LEVEL>1</LEVEL>
            <PARENT_ITEM>331-4437</PARENT_ITEM>
            <ITEM>1234</ITEM>
            <QTY>1</QTY>
            <REV>A02-00</REV>
            <STATUS>B</STATUS>
            <ITEM_MOST_ACTIVE_STATUS>B</ITEM_MOST_ACTIVE_STATUS>
        </XYZ>
    </XYZ>
</ABCD>

1 个答案:

答案 0 :(得分:0)

您不能只对递归结构进行排序。您将失去层次结构。请尝试以下使用xml linq的代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Linq;


namespace ConsoleApplication62
{

    class Program
    {
        const string INPUT_FILENAME = @"c:\temp\test.xml";
        const string OUTPUT_FILENAME = @"c:\temp\test2.xml";
        static void Main(string[] args)
        {
            new Node(INPUT_FILENAME, OUTPUT_FILENAME);
        }


    }
    public class Node
    {
        public static Node root = new Node();

        public List<Node> children { get; set; }

        public int level { get; set; }
        public string item { get; set; }
        public int qty { get; set; }
        public string rev { get; set; }
        public string status { get; set; }
        public string mostActive { get; set; }

        public Node() { }
        public Node(string in_filename, string out_filename)
        {
            XDocument doc = XDocument.Load(in_filename);

            XElement xmlRoot = doc.Root;
            GetNodesRecursive(root, xmlRoot);

            SortItemRecursive(root);

            XElement newDoc = new XElement("ABCD");
            GetXmlRecursive(root, newDoc);

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.NewLineHandling = NewLineHandling.Entitize;
            XmlWriter writer = XmlWriter.Create(out_filename, settings);
            writer.WriteRaw(newDoc.ToString());
            writer.Flush();
            writer.Close();


        }
        public void GetNodesRecursive(Node parent, XElement xmlParent)
        {
            foreach (XElement xyz in xmlParent.Elements("XYZ"))
            {
                if (parent.children == null)
                {
                    parent.children = new List<Node>();
                }
                Node newChild = new Node();
                parent.children.Add(newChild);

                newChild.level = (int)xyz.Element("LEVEL");
                newChild.item = (string)xyz.Element("ITEM");
                newChild.qty = (int)xyz.Element("QTY");
                newChild.rev = (string)xyz.Element("REV");
                newChild.status = (string)xyz.Element("STATUS");
                newChild.mostActive = (string)xyz.Element("ITEM_MOST_ACTIVE_STATUS");

                GetNodesRecursive(newChild, xyz);
            }
        }
        public void GetXmlRecursive(Node parent, XElement xmlParent)
        {
            xmlParent.Add(new object[] {
                new XElement("LEVEL", parent.level),
                new XElement("ITEM", parent.item),
                new XElement("QTY", parent.qty),
                new XElement("REV", parent.rev),
                new XElement("STATUS", parent.status),
                new XElement("ITEM_MOST_ACTIVE_STATUS", parent.mostActive)
            });

            if (parent.children != null)
            {
                foreach (Node node in parent.children)
                {
                    XElement child = new XElement("XYZ");
                    xmlParent.Add(child);
                    GetXmlRecursive(node, child);
                }
            }
        }
        public void SortItemRecursive(Node parent)
        {
            if (parent.children != null)
            {
                parent.children = parent.children.OrderBy(x => x.item).ToList();
                foreach (Node child in parent.children)
                {
                    SortItemRecursive(child);
                }
            }
        }
    }
}