Im working on compiling a list using XML and PHP. I’m looking to find the first “destination tag” found in the RailVehicleStateClass for each train ID and echo it out. I tried doing a foreach loop to gather the destination tag but it just loops the same data for each train ID until the end of the xml file. Below is a snippet of the XML file, the full version has well over 700 entries and each train can have anywhere from 1 to 100+ railvehiclaes associated with it.
XML
<ScnLoader xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<trainList>
<TrainLoader>
<trainID>99991</trainID>
<TrainWasAI>false</TrainWasAI>
<DispatchTrainDirection>0</DispatchTrainDirection>
<ManuallyAppliedSpeedLimitMPH>2147483647</ManuallyAppliedSpeedLimitMPH>
<PreviousSignalInstruction>Clear</PreviousSignalInstruction>
<unitLoaderList>
<RailVehicleStateClass>
<destinationTag>TRC SVMS</destinationTag>
</RailVehicleStateClass>
<RailVehicleStateClass>
<destinationTag>PRC</destinationTag>
</RailVehicleStateClass>
</unitLoaderList>
</TrainLoader>
</trainList>
</ScnLoader>
PHP
<?php
$trains = simplexml_load_file("Auto%20Save%20World.xml") or die("Error: Cannot create object");
$totalUnitCount=0;
echo "<table>";
echo "<th>#</th>";
echo "<th>Train ID</th>";
echo "<th>Symbol</th>";
echo "<th>Direction</th>";
echo "<th>AI</th>";
foreach ($trains->xpath("//TrainLoader") as $train) {
$totalUnitCount = $totalUnitCount + 1;
foreach (array_slice($trains->xpath("//RailVehicleStateClass"),0,1) as $unit){
echo $unit->destinationTag;
}
echo "</td>";
echo "<td>";
echo $train->DispatchTrainDirection;
echo "</td>";
echo "<td>";
echo $train->TrainWasAI;
echo "</td>";
}
?>
2
Answers
Your
xpath
query to get theRailVehicleStateClass
elements needs to be made relative to the current$train
. You can do that using:Note the use of
.
in front of//
to make the path relative to the current$train
element.First you need to use the foreach in the unitLoaderList, then you the xpath in the object you create from the foreach and add a
.
before the//
in the query to only obtain what is inside the object.I really don’t understand what you want to accomplish with HTML table, but here is an example code that work with your file and multiple trains without HTML.