skip to Main Content

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


  1. Your xpath query to get the RailVehicleStateClass elements needs to be made relative to the current $train. You can do that using:

    $train->xpath(".//RailVehicleStateClass")
    

    Note the use of . in front of // to make the path relative to the current $train element.

    Login or Signup to reply.
  2. 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.

            $trains = simplexml_load_file("train.xml") or die("Error: Cannot create object");   
            $totalUnitCount=0;
            foreach ($trains->xpath("//trainList") as $train) {
                $totalUnitCount = $totalUnitCount + 1;
                foreach ($train->xpath(".//unitLoaderList") as $unit){
                    foreach ($unit->xpath(".//RailVehicleStateClass") as $railV){
                        echo $railV->destinationTag[0]; //Assuming all RailVehicle has at list one destination tags if not you has to another foreach with xpath of destinationTag and only get the first one
                    }
                }
            }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search