按名称,属性名称,属性值,元素值对XML进行排序

时间:2015-10-15 13:43:24

标签: c# xml linq

我希望 Sort XML element Name ,然后 Attribute Name & Attribute value 然后通过 element value 将结果再次保存在带有注释,空格的XML文件中。

我使用LINQ实现了这个upto元素名称和元素的值,但现在我在使用属性名称及其值进行排序时遇到了问题。

    private void SortnSave(string filePath, string savePath)
    {
        var xDoc = XDocument.Load(filePath);
        var result = Sort(xDoc.Root);
        result.Save(savePath);
    }

    private XElement Sort(XElement element)
    {
        var xe = new XElement(element.Name, element.Elements().OrderBy(x => x.Name.ToString(), new SplitComparer())
            .ThenBy(x => x.Value.ToString(), new SplitComparer()).Select(x => Sort(x)));

        if (!xe.HasElements)
        {
            xe.Value = element.Value;
        }

        if (element.HasAttributes)
        {
            foreach (XAttribute item in element.Attributes().OrderBy(x => x.Name.ToString()).ThenBy(x => x.Value.ToString()))
            {
                xe.Add(item);
            }
        }

        return xe;
    }

    public class SplitComparer : IComparer<string>
    {
        public int Compare(string x, string y)
        {
            var partsOfX = x.Split('.');

            int firstNumber;
            if (partsOfX.Length > 1 && int.TryParse(partsOfX[1], out firstNumber))
            {
                var secondNumber = Convert.ToInt32(y.Split('.')[1]);

                return firstNumber.CompareTo(secondNumber);
            }

            return x.CompareTo(y);
        }
    }

如何在元素名称和元素值排序条件之间的linq查询下面添加属性名称和属性值排序条件

var xe = new XElement(element.Name, element.Elements().OrderBy(x => x.Name.ToString(), new SplitComparer())
            .ThenBy(x => x.Value.ToString(), new SplitComparer()).Select(x => Sort(x)));

示例XML:

<Coordinates>
<Coordinate Name="P" Value="C">
<Y>0</Y>
<X>0</X>    
</Coordinate>
<Coordinate Name="Q" Value="D">
    <X>50</X>
    <Y>25</Y>
</Coordinate>
<Coordinate Value="D" Name="Z" >
    <X>100</X>
    <Y>100</Y>
</Coordinate>
</Coordinates>

结果:

<?xml version="1.0" encoding="utf-8"?>
<Coordinates>
<Coordinate Name="P" Value="C">
<X>0</X>
<Y>0</Y>
</Coordinate>
<Coordinate Name="Z" Value="D">
<X>100</X>
<Y>100</Y>
</Coordinate>
<Coordinate Name="Q" Value="D">
<X>50</X>
<Y>25</Y>
</Coordinate>
</Coordinates>

预期结果:

<?xml version="1.0" encoding="utf-8"?>
<Coordinates>
<Coordinate Name="P" Value="C">
<X>0</X>
<Y>0</Y>
</Coordinate>
<Coordinate Name="Q" Value="D">
<X>50</X>
<Y>25</Y>
</Coordinate>
<Coordinate Name="Z" Value="D">
<X>100</X>
<Y>100</Y>
</Coordinate>
</Coordinates>

更新:

我通过创建所有已排序属性的字符串并在linq查询中进行比较来实现此目的。

  var xe = new XElement(element.Name, element.Elements().OrderBy(x => x.Name.ToString(), new SplitComparer()).ThenBy(x => GetAttributeWithValueString(x))
            .ThenBy(x => x.Value.ToString(), new SplitComparer()).Select(x => Sort(x)));

    private string GetAttributeWithValueString(XElement element)
    {
        string attrStr = string.Empty;

        if (element.HasAttributes)
        {
            foreach (XAttribute item in element.Attributes().OrderBy(x => x.Name.ToString()).ThenBy(x => x.Value.ToString()))
            {
                attrStr += item.ToString() + " ";
            }
        }

        return attrStr;
    }      

但这是一个好方法吗?有人能建议我比这更好吗?

0 个答案:

没有答案