I have an XML that has various elements, but one of them named RowId, I'd like to move to the top of the respective XML array...essentially sorting the elements in my way. My below code can be copied/pasted for you to test with.
What's the best way to accomplish this? And/or is there a better way than what I'm doing now? This seems clumsy.
Why does the below code work if I include
| Sort-Object -Property "Name"?
Copy & Paste below code:
$rawXML = [xml]@"
<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Document">
<xs:complexType>
<xs:sequence>
<xs:element name="Object1" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Element1" nillable="true">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="80"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Element2" nillable="true">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="-1"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="RowId">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="20"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Object2" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Element4" nillable="true">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="80"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Element5" nillable="true">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="-1"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="RowId">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="20"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
"@
$rawXML.schema.element.complexType.sequence.element.complexType.sequence | ForEach-Object {
$sequence = $_
# This does NOT work
$childNodes = $sequence.ChildNodes #| Sort-Object -Property "Name"
$childNodes.Count # Output = 3
$sequence.RemoveAll()
$childNodes.Count # Output = 0
# This DOES work; Only difference is '| Sort-Object -Property "Name"'
<#
$childNodes = $sequence.ChildNodes | Sort-Object -Property "Name"
$childNodes.Count # Output = 3
$sequence.RemoveAll()
$childNodes.Count # Output = 3
#>
$childNodes | ForEach-Object {
$child = $_
if ($child.Name -eq "RowId") {
$sequence.InsertBefore($child, $sequence.FirstChild)
} else {
$sequence.AppendChild($child) | out-null
}
}
}
$rawXML.InnerXml