XML parsing multi values?

by Dwayne Dibbley at 2012-09-19 10:01:21

i have the following xml


<?xml version="1.0" encoding="utf-8" standalone="no" ?>
<fieldData>
<map name="Default" numFields="34" maxCoords="60">
<field name="Field 1" area="27846" hectares="2.784600019455" acres="6.880747795105">
<coordinates startX="693" startZ="92" endX="707" endZ="96" />
<coordinates startX="693" startZ="97" endX="722" endZ="101" />
<coordinates startX="688" startZ="102" endX="737" endZ="106" />
<status num="2" density="105448" />
</field>
<field name="Field 2" area="10373" hectares="1.037299990654" acres="2.5631682872772">
<coordinates startX="911" startZ="161" endX="1025" endZ="165" />
<coordinates startX="906" startZ="166" endX="1025" endZ="180" />
<coordinates startX="901" startZ="181" endX="1025" endZ="195" />
<status num="2" density="40516" />
<fruit name="wheat">
<growth num="5" density="39828" />
</fruit>
</field>
<field name="Field 3" area="12922" hectares="1.2922003269196" acres="3.1930255889893">
<coordinates startX="212" startZ="531" endX="303" endZ="673" />
<status num="2" density="51300" />
<fruit name="rape">
<growth num="5" density="50346" />
</fruit>
</field>
</map>
</fieldData>


whay i am trying to do is for each field, loop through all the coordinates and call a function the the values of startX startZ endX endZ

so i can open the xml and loop through them all with

$myxml = [xml](Get-Content .\fieldData.xml)
$myxml.fieldData.map.field | foreach { $.coordinates }


and results in

startX startZ endX endZ
------ ------ ---- ----
693 92 707 96
693 97 722 101
688 102 737 106
688 107 752 111


question is how do i get the startx startz etc to call a function?

also i would like it to result in the following so the multiple coordinates can be associated with the field:

field 1
startX startZ endX endZ
field 2
startX startZ endX endZ


Thanks
by surveyor at 2012-09-20 04:31:53
Hi Dwayne,
maybe this makes it a bit clearer:
Clear-Host

$myxml = [xml]@"
<?xml version="1.0" encoding="utf-8" standalone="no" ?>
<fieldData>
<map name="Default" numFields="34" maxCoords="60">
<field name="Field 1" area="27846" hectares="2.784600019455" acres="6.880747795105">
<coordinates startX="693" startZ="92" endX="707" endZ="96" />
<coordinates startX="693" startZ="97" endX="722" endZ="101" />
<coordinates startX="688" startZ="102" endX="737" endZ="106" />
<status num="2" density="105448" />
</field>
<field name="Field 2" area="10373" hectares="1.037299990654" acres="2.5631682872772">
<coordinates startX="911" startZ="161" endX="1025" endZ="165" />
<coordinates startX="906" startZ="166" endX="1025" endZ="180" />
<coordinates startX="901" startZ="181" endX="1025" endZ="195" />
<status num="2" density="40516" />
<fruit name="wheat">
<growth num="5" density="39828" />
</fruit>
</field>
<field name="Field 3" area="12922" hectares="1.2922003269196" acres="3.1930255889893">
<coordinates startX="212" startZ="531" endX="303" endZ="673" />
<status num="2" density="51300" />
<fruit name="rape">
<growth num="5" density="50346" />
</fruit>
</field>
</map>
</fieldData>
"@


function test-function ($Name,$Coordinates) {
$Name
foreach ($c in $Coordinates) {
"{0} {1} {2} {3}" -f $c.StartX,$c.StartZ,$c.EndX,$c.EndZ
}
}

$myxml.fieldData.map.field | ForEach-Object { test-function $
.name $.coordinates }
by Dwayne Dibbley at 2012-09-21 10:20:11
Many thanks for that i have now added a drawing element to the function based on the field content as follows:

Clear-Host

Add-Type -AssemblyName System.Drawing

$filename = "$home\foo.png"
$bmp = new-object System.Drawing.Bitmap 3000,3000
$g = [System.Drawing.Graphics]::FromImage($bmp)

$myxml = [xml](Get-Content .\fieldData.xml)

function test-function ($Name,$Coordinates,$Fruit) {
$Name + " " + $Fruit
$pencolour = "Black"
if ($Fruit -eq "grass") {
$pencolour = "Green"
}
foreach ($c in $Coordinates) {
"{0} {1} {2} {3}" -f $c.StartX,$c.StartZ,$c.EndX,$c.EndZ
$g.drawRectangle([System.Drawing.Pens]::$pencolour,$c.StartX,$c.StartZ,$c.EndX-$c.StartX,$c.EndZ-$c.StartZ)
$g.FillRectangle([System.Drawing.Brushes]::$pencolour,$c.StartX,$c.StartZ,$c.EndX-$c.StartX,$c.EndZ-$c.StartZ)
}
}

$myxml.fieldData.map.field | ForEach-Object { test-function $
.name $.coordinates $.fruit.name}

$bmp.Save($filename)

Invoke-Item $filename