Hei
i got a quick question.
I want to upload an XML File and echo it through a for loop.
This is my XML:
<notfall>
<mitarbeiter>
<vorname>Thomas</vorname>
<name>Meier</name>
<handynummer>01701427475</handynummer>
<gruppen>EDV</gruppen>
</mitarbeiter>
<mitarbeiter>
<vorname>Max</vorname>
<name>Mustermann</name>
<handynummer>012441212415</handynummer>
<gruppen>EDV, Immo</gruppen>
</mitarbeiter>
</notfall>
This is php code:
<?php
$notfall=simplexml_load_file ("notfall.xml");
echo $notfall->mitarbeiter[0]->handynummer;
$countnotfall = count($notfall);
for($i=0;$i<$countnotfall;$i++){
echo $notfall ->mitarbeiter[2]->vorname;
}
?>
I want to echo every name of my array without hard coding every line.
Can you tell me how i can do that?
You should be able to just loop over all of the <mitarbeiter> and output the data of each item...
$notfall=simplexml_load_file ("notfall.xml");
foreach ( $notfall->mitarbeiter as $mitarbeiter ) {
echo $mitarbeiter->handynummer.PHP_EOL;
echo $mitarbeiter->vorname.PHP_EOL;
}
Related
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>";
}
?>
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.
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
}
}
}
I am extracting XML data using DOMDocument and foreach loops. I am pulling certain attributes and node values from the XML document and creating variables with that data. I am then echoing the variables.
I have successfully completed this for the first portion of the XML data that lives between the <VehicleDescription tags. However, using the same logic with data within the <style> tags, I have been having issues. Specially, the created variables won't echo unless they are in the foreach loop. See the code below for clarification.
My php:
<?php
$vehiclexml = $_POST['vehiclexml'];
$xml = file_get_contents($vehiclexml);
$dom = new DOMDocument();
$dom->loadXML($xml);
//This foreach loop works perfectly, the variables echo below:
foreach ($dom->getElementsByTagName('VehicleDescription') as $vehicleDescription){
$year = $vehicleDescription->getAttribute('modelYear');
$make = $vehicleDescription->getAttribute('MakeName');
$model = $vehicleDescription->getAttribute('ModelName');
$trim = $vehicleDescription->getAttribute('StyleName');
$id = $vehicleDescription->getAttribute('id');
$BodyType = $vehicleDescription->getAttribute('altBodyType');
$drivetrain = $vehicleDescription->getAttribute('drivetrain');
}
//This foreach loop works; however, the variables don't echo below, the will only echo within the loop tags. How can I resolve this?
foreach ($dom->getElementsByTagName('style') as $style){
$displacement = $style->getElementsByTagName('displacement')->item(0)->nodeValue;
}
echo "<b>Year:</b> ".$year;
echo "<br>";
echo "<b>Make:</b> ".$make;
echo "<br>";
echo "<b>Model:</b> ".$model;
echo "<br>";
echo "<b>Trim:</b> ".$trim;
echo "<br>";
echo "<b>Drivetrain:</b> ".$drivetrain;
echo "<br>";
//Displacement will not echo
echo "<b>Displacement:</b> ".$displacement;
?>
Here is the XML file it is pulling from:
<VehicleDescription country="US" language="en" modelYear="2019" MakeName="Toyota" ModelName="RAV4" StyleName="LE" id="1111" altBodyType="SUV" drivetrain="AWD">
<style modelYear="2019" name="Toyota RAV4 LE" passDoors="4">
<make>Toyota</make>
<model>RAV4</model>
<style>LE</style>
<drivetrain>AWD</drivetrain>
<displacement>2.5 liter</displacement>
<cylinders>4-cylinder</cylinders>
<gears>8-speed</gears>
<transtype>automatic</transtype>
<horsepower>203</horsepower>
<torque>184</torque>
</style>
</VehicleDescription>
Any help or insight as to why variables from the first foreach loop echo but variables from the second don't would be greatly appreciated.
Thanks!
Just to post an alternative solution to the way you've fixed this.
As you've, there are a couple of <stlye> tags, this means that the foreach will attempt to use all style tags. But as you know that you are after the contents of the first tag only, you can drop the foreach loop and use the item() method...
$displacement = $dom->getElementsByTagName('style')->item(0)
->getElementsByTagName('displacement')->item(0)->nodeValue;
This also applies to how you fetch the data from the <VehicleDescription> tag. Drop the foreach and use
$vehicleDescription = $dom->getElementsByTagName('VehicleDescription')->item(0);
The error was within the XML document.
Within the <style> tags was another set of <style> tags. Changing the name of the second set solved this issue.
I'm trying to use 2 xml files to put data on to a list. One Xml file is not editable by me the 2nd is a reference database of sorts that I created. Both files have a common string for <rvXMLfilename> and if both xml file strings match I want to echo out a string from XML file 2. I attmepted to write this in my php script but I could not get it to work.
$railunit = simplexml_load_file('railUnitList.xml');
$orders = simplexml_load_file('train.xml');
foreach ($orders->xpath("//RailVehicleStateClass") as $traininfo):
$rvXMLfilename=$traininfo->rvXMLfilename;
$unitType=$traininfo->unitType;
$unitNumber=$traininfo->unitNumber;
$destinationTag=$traininfo->destinationTag;
$loadWeightUSTons=$traininfo->loadWeightUSTons;
echo "<tr>";
echo "<td>";
if($railunit->rvXMLfilename == $orders->rvXMLfilename){
echo $railunit->unitType;
}else{
echo "error!";
}
XML File 1
<?xml version="1.0"?>
<ScnLoader xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<trainList>
<TrainLoader>
<unitLoaderList>
<RailVehicleStateClass>
<rvXMLfilename>R8_SD40T-2_UP03.xml</rvXMLfilename>
<unitType>US_DieselEngine</unitType>
<loadWeightUSTons>14.2985783</loadWeightUSTons>
<destinationTag>MDTLA</destinationTag>
<unitNumber>8626</unitNumber>
</RailVehicleStateClass>
<RailVehicleStateClass>
<rvXMLfilename>R8_SD40T-2_UP01.xml</rvXMLfilename>
<unitType>US_DieselEngine</unitType>
<loadWeightUSTons>14.2985792</loadWeightUSTons>
<destinationTag>None</destinationTag>
<unitNumber>4401</unitNumber>
</RailVehicleStateClass>
<RailVehicleStateClass>
<rvXMLfilename>R8_SD40T-2_UP01.xml</rvXMLfilename>
<unitType>US_DieselEngine</unitType>
<loadWeightUSTons>14.2985783</loadWeightUSTons>
<destinationTag>None</destinationTag>
<unitNumber>4454</unitNumber>
</RailVehicleStateClass>
</unitLoaderList>
</TrainLoader>
</trainList>
</ScnLoader>
XML File 2
<railUnitList>
<railUnit>
<rvXMLfilename>R8_SD40T-2_UP01.xml</rvXMLfilename>
<unitType>SD40-2T Locomotive</unitType>
<reportingMark>UP</reportingMark>
<axelCount>6</axelCount>
<unitWeight></unitWeight>
<unitLength>71</unitLength>
</railUnit>
<railUnit>
<rvXMLfilename>R8_CoveredHopper_ACF2970_BN01.xml</rvXMLfilename>
<unitType>Covered Hopper</unitType>
<reportingMark>BN</reportingMark>
<axelCount>4</axelCount>
<unitWeight></unitWeight>
<unitLength>60</unitLength>
</railUnit>
<railUnit>
<rvXMLfilename>R8_C14Hopper_POTASH01.xml</rvXMLfilename>
<unitType>Covered Hopper</unitType>
<reportingMark>POTX</reportingMark>
<axelCount>4</axelCount>
<unitWeight></unitWeight>
<unitLength>60</unitLength>
</railUnit>
<railUnit>
<rvXMLfilename>Run8_Tank107BN01.xml</rvXMLfilename>
<unitType>Tank</unitType>
<reportingMark>BN</reportingMark>
<axelCount>4</axelCount>
<unitWeight></unitWeight>
<unitLength>59</unitLength>
</railUnit>
</railUnitList>
There are a couple of issues with your code. Firstly you cannot directly refer to the value of a SimpleXMLElement as e.g. $rvXMLfilename=$traininfo->rvXMLfilename; you need to cast it to the appropriate type. Secondly rvXMLfilename is not a child of $railunit. I think you probably want to iterate through the values in your $railunit, comparing each of them with the values you extract from the $orders XML. This code should achieve what you want:
foreach ($orders->xpath("//RailVehicleStateClass") as $traininfo) {
$rvXMLfilename=(string)$traininfo->rvXMLfilename;
$unitType=(string)$traininfo->unitType;
$unitNumber=(int)$traininfo->unitNumber;
$destinationTag=(string)$traininfo->destinationTag;
$loadWeightUSTons=(float)$traininfo->loadWeightUSTons;
echo "<tr>";
echo "<td>";
$message = "error!";
foreach ($railunit->railUnit as $ru) {
if((string)$ru->rvXMLfilename == $rvXMLfilename){
$message = (string)$ru->unitType;
}
}
echo $message;
}
Output (for your sample data)
<tr><td>error!<tr><td>SD40-2T Locomotive<tr><td>SD40-2T Locomotive
Again use the XPath query to get the values you're looking for. Stick all the filenames into an array, for easier comparison later.
<?php
$railunit = simplexml_load_file('railUnitList.xml');
$orders = simplexml_load_file('train.xml');
foreach ($railunit->railUnit as $railunit) {
$key = (string)$railunit->unitType;
$value = (string)$railunit->rvXMLfilename;
$filenames[$key] = $value;
}
foreach ($orders->xpath("//RailVehicleStateClass") as $traininfo) {
$rvXMLfilename=$traininfo->rvXMLfilename;
$unitType=$traininfo->unitType;
$unitNumber=$traininfo->unitNumber;
$destinationTag=$traininfo->destinationTag;
$loadWeightUSTons=$traininfo->loadWeightUSTons;
echo "<tr>";
echo "<td>";
if(in_array($traininfo->rvXMLfilename, $filenames)){
echo array_search($traininfo->rvXMLfilename, $filenames);
} else {
echo "error!";
}
}
Note also your use of $orders->rvXMLfilename in the original code. The PHP structure is the same as the XML structure, you can't reference an element in that fashion unless it's the direct child of the root element.
Trying to scrape an IKEA page at the following link:
http://www.ikea.com/it/it/catalog/products/60255550/?type=xml&dataset=prices
I want to scrape the price of the item, but in the xml file the price appears once unformatted and once with the Euro sign next to it. I wish to scrape the priceNormal unformatted value specifically.
<prices>
<normal>
<priceNormal unformatted="44.99">€ 44,99</priceNormal>
<pricePrevious/>
<priceNormalPerUnit/>
<pricePreviousPerUnit/>
</normal>
My code below doesn't echo the price at all, not sure where I'm going wrong :(
$string = 'http://www.ikea.com/it/it/catalog/products/60255550/?type=xml&dataset=prices';
$xml=simplexml_load_file($string) or die("Error: Cannot create object");
//print_r($xml);
echo $xml->product->prices;
You should be able to get the price with
$xml->products->product->items->item->prices->normal->priceNormal
$xml->products->product->items->item->prices->normal->priceNormal->attributes()->unformatted
If you however need to iterate of a result set, you can break up the places where you are expecting multiples with iteration...
foreach( $xml->products->product as $product )
{
echo $product->name;
foreach( $product->items->item as $item )
{
echo $item->name;
echo $item->prices->normal->priceNormal;
echo $item->prices->normal->priceNormal->attributes()->unformatted;
}
}
Try using var_dump() instead of print_r() to look at the value of $xml. It's a bit convoluted, but you'll find the data you're looking for at this location:
$xml->products[0]->product->items[0]->item->prices->normal->priceNormal[0];
I'm working on a WordPress site and am using a plugin called 'Simple Fields', to add data to repeatable fields. I've entered data into three fields: (audioinfo, audiofile, audiocomposer).
I would now like to create a post that displays that information in the following way:
Audio Info 1
Audio File 1
Audio Composer 1
~~~
Audio Info 2
Audio File 2
Audio Composer 2
I've been trying to figure this out with foreach. Here's the closest I can arrive at (thought I know it's invalid). Can anyone make any suggestions of how to handle this?
<?php
$audioinfo = simple_fields_values("audioinfo");
$audiofile = simple_fields_values("audiofile");
$audiocomposer = simple_fields_values("audiocomposer")
foreach ($audioinfo as $audioinfos, $audiofile as $audiofiles, $audiocomposer as $audiocomposers){
echo $audioinfos;
echo $audiofile;
echo $audiocomposer;
}
?>
(Just as a side note, in case it's important, the first three lines appear to all be valid - that is, if I do a "foreach" on $audiocomposer alone, I successfully get: Bach Handel Beethoven.)
Is there something I can do to apply "foreach" to all three at the same time?
Thanks!
Assuming all the arrays of same length, making use of a normal for loop.
<?php
$audioinfo = simple_fields_values("audioinfo");
$audiofile = simple_fields_values("audiofile");
$audiocomposer = simple_fields_values("audiocomposer");
for($i=0;$i<count($audioinfo);$i++)
{
echo $audioinfo[$i];
echo $audiofile[$i];
echo $audiocomposer[$i];
}
?>
One more pretty solution:
<?php
$audioinfo = simple_fields_values("audioinfo");
$audiofile = simple_fields_values("audiofile");
$audiocomposer = simple_fields_values("audiocomposer");
foreach ($audioinfo as $k => $val){
echo $val;
echo $audiofile[$k];
echo $audiocomposer[$k];
}
?>
Assuming there are always going to be the same number of items in all 3 arrays, you could do something like this:
$items = count($audioinfo);
for ($i = 0; $i < $items; $i++)
{
echo $audioinfo[$i];
echo $audiofile[$i];
echo $audiocomposer[$i];
}
here i gave one example how to handle the 3 array value in single foreach , hope it will much help to you
$audioinfo =array('popsong','rocksong','molodysong');
$audiofile=array('jackson','rahman','example');
$audiocomposer =array('first','second','third');
foreach($audioinfo as $key => $value)
{
echo $value."</br>";
echo $audiofile[$key]."</br>";
echo $audiocomposer[$key]."</br>";
}