1

我正在对一些 XML 进行排序,并希望根据特定的非唯一属性对元素进行排序,这允许我对类似元素进行分组。在这些组中,我需要保持原来的顺序。问题是,在排序时,这些组内的顺序会发生变化,而在重新排序时,顺序会再次发生变化。如果 XML 的内容没有改变(否则 SVN 差异很难看),我需要一种不会改变事物的排序。这是一个简化的示例:

$xml = [xml]@"
<root>
  <element name="a" number="1" />
  <element name="b" number="1" />
  <element name="c" number="1" />
  <element name="d" number="2" />
  <element name="e" number="2" />
  <element name="f" number="2" />
  <element name="g" number="3" />
  <element name="h" number="3" />
</root>
"@

Write-Host "`nFirst Sort produces this:"
$result1 = $xml.SelectNodes('//element') | Sort-Object -Property 'number'
Write-Host (($result1 | select -ExpandProperty 'number') + " <---Sorted on")
Write-Host (($result1 | select -ExpandProperty 'name') + " <---Order not maintained")

Write-Host "`nSorting the (already sorted) results of First Sort produces this:"
$result2 = $result1 | Sort-Object -Property 'number'
Write-Host (($result2 | select -ExpandProperty 'number') + " <---Sorted on")
Write-Host (($result2 | select -ExpandProperty 'name') + " <---Order changed again")

这是输出:

First Sort produces this:
1 1 1 2 2 2 3 3  <---Sorted on
c b a f e d h g  <---Order not maintained

Sorting the (already sorted) results of First Sort produces this:
1 1 1 2 2 2 3 3  <---Sorted on
a b c d e f g h  <---Order changed again

在此示例中,我需要在“数字组”中保留原始“名称”排序。

Can anyone think of an easy way to make this maintain the original order and come out the same when sorting multiple times?

I'm trying to avoid adding dummy attributes representing the original ordering. Maybe there is a different .NET sorting function that's more deterministic? I searched but nobody seemed to be concerned with ordering within equivalent groups.

Thanks.

4

2 回答 2

1

If you don't have something that already represents the natural sort order, you can just add an index property with Add-Member:

$nodes = @($xml.SelectNodes('//element'))
for ($i=0; $i -lt $nodes.Count; $i++) 
{
    $nodes[$i] = $nodes[$i] | Add-Member -MemberType NoteProperty "Index" $i -PassThru
}

$result1 = $nodes | Sort-Object name, Index

Then you are guaranteed to get the same ordering no matter how many times you re-sort.

Update: added syntax for PowerShell v2

于 2012-04-23T20:38:35.227 回答
0

Sort with respect to both the properties:

$xml.SelectNodes('//element') | Sort-Object -Property number, name

This produces this output:

name     number
----     ------
a        1
b        1
c        1
d        2
e        2
f        2
g        3
h        3
于 2012-04-23T18:05:26.020 回答