RunawayPhish RunawayPhish - 1 year ago 70
PHP Question

Need to use php foreach to create XML elements and attributes using a second XML

I have an XML doc (

traffic.xml
) that I then used PHP to pull only 2 specific attributes using foreach as there is a ton of them in the original XML to create a PHP(
drivetimeFetch.php
).

What I need to do now is, using
drivetimeFetch.php
, I need to create another xml doc (
carousel_Traffic.xml
) with elements and attributes made up of the 30 or so lines from the stripped
drivetimeFetch.php
I created. Here is where I'm getting stuck. I was able to write the elements and attributes but how do I get each line into its own element block.

Here is what my php looks like:

<?php
$xml1 = new SimpleXMLElement(file_get_contents('https://wsidata.weather.com/201303/en-us/55828880/traffic.xml'));
foreach ($xml1->drivetimes->drivetime as $drivetime) {
echo"<br>";
echo $drivetime['pathName'].":"." ".$drivetime['driveTimeMinutes']."min \n" ;
}
$xml_txt = '<?xml version="1.0" encoding="UTF-8"?>'."\r\n".'<tickerfeed version="2.4">'."\r\n".
'<playlist type="scrolling_carousel" name="TrafficScroll" target="carousel">'."\r\n" ;
$element = '<element>';
$elementClose = '</element>';
$field1 = '<field name="05">';
$fieldClose = '</field>';
$playlistClose = '</playlist>';
$tickerfeedClose = '</tickerfeed>';

$f = fopen("C:\\Users\\Administrator\\Desktop\\carousel_Traffic.xml", "w");
fwrite ($f, $xml_txt. "\r\n" );
fwrite ($f, $element. "\r\n" );
fwrite ($f, $field1. $drivetime['pathName'].":"." ".$drivetime['driveTimeMinutes']."min " . $fieldClose. "\r\n" );
fwrite ($f, $elementClose. "\r\n" );
fwrite ($f, $playlistClose. "\r\n" );
fwrite ($f, $tickerfeedClose. "\r\n" );
fclose ($f);
?>


What I need from this is to get that carousel_Traffic.xml to look like is this:

<?xml version="1.0" encoding="UTF-8"?>
<tickerfeed version="2.4">
<playlist type="scrolling_carousel" name="TrafficScroll" target="carousel">

<element>
<field name="05">I-278: Bklyn Battery Tunnel to Brooklyn Bridge: 10min </field>
</element>
</playlist>
</tickerfeed>


For every one of those lines in the
drivetimeFetch.php
, I'm guessing this is a foreach operation but I have no idea how to do that so that the
pathName
and
driveTimeMinutes
for each line gets its own element block. As you can see, I got it to work for only one line.

Answer Source

Consider XSLT to transform the input XML into your end output. No loop or string concatenation of XML document is needed:

// LOAD XML SOURCE
$xml1 = new SimpleXMLElement(file_get_contents('https://wsidata.weather.com/201303/en-us/55828880/traffic.xml'));

// XSLT STRING
$xslstr = '<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
             <xsl:output version="1.0" encoding="UTF-8" method="xml" indent="yes" />
             <xsl:strip-space elements="*"/>

              <xsl:template match="node()|@*">
                <xsl:copy>
                  <xsl:apply-templates select="node()|@*" />
                </xsl:copy>
              </xsl:template>

              <xsl:template match="traffic">
                  <tickerfeed version="2.4">
                      <playlist type="scrolling_carousel" name="TrafficScroll" target="carousel">            
                          <xsl:apply-templates select="drivetimes" />
                      </playlist>
                  </tickerfeed>
              </xsl:template>

              <xsl:template match="incidents"/>

              <xsl:template match="drivetimes">
                  <element>
                      <template>Traffic</template>
                      <xsl:apply-templates select="drivetime"/>
                  </element>
              </xsl:template>

              <xsl:template match="drivetime">
                  <field name="05"><xsl:value-of select="concat(@pathName, \': \', @driveTimeMinutes, \'min\')"/></field>
              </xsl:template>

           </xsl:stylesheet>';

$xslfile = new SimpleXMLElement($xslstr);

// TRANSFORM XML with XSLT
$proc = new XSLTProcessor;
$proc->importStyleSheet($xslfile); 
$newXML = $proc->transformToXML($xml1);

// OUTPUT TO FILE
file_put_contents('C:\\Users\\Administrator\\Desktop\\carousel_Traffic.xml', $newXML);

Output

<?xml version="1.0" encoding="UTF-8"?>
<tickerfeed version="2.4">
  <playlist type="scrolling_carousel" name="TrafficScroll" target="carousel">
    <element>
      <template>Traffic</template>
      <field name="05">I-95: Bruckner Interchange to I-95 Northbound - Midland Ave/Exit 22: 22min</field>
    </element>
    <element>
      <template>Traffic</template>
      <field name="05">Belt Pkwy: Verrazano Brg to Southern State Pkwy E Eastbound - Nassau/Queens County Line: 62min</field>
    </element>
    <element>
      <template>Traffic</template>
      <field name="05">I-95 Northbound - Alexander Hamilton Brg to Bruckner Interchange: 14min</field>
    </element>
    <element>
      <template>Traffic</template>
      <field name="05">Bronx River Pkwy:  Cross County Pkwy to Bruckner Expressway: 37min</field>
    </element>
    <element>
      <template>Traffic</template>
      <field name="05">I-278: Verrazano to Belt Merge: 3min</field>
    </element>
    <element>
      <template>Traffic</template>
      <field name="05">Belt Pkwy: Southern State Pkwy to Van Wyck Expwy: 8min</field>
    </element>
    <element>
      <template>Traffic</template>
      <field name="05">Belt Pkwy: Ocean Pkwy to Verrazano Brg: 9min</field>
    </element>
    <element>
      <template>Traffic</template>
      <field name="05">Verrazano Brg to Brooklyn Brg: 2min</field>
    </element>
    <element>
      <template>Traffic</template>
      <field name="05">NYS Thruway: I-287 to Tappan Zee Bridge Tolls: 17min</field>
    </element>
    <element>
      <template>Traffic</template>
      <field name="05">Major Deegan Expwy: Macombs Dam Brg to Third Ave Bridge: 2min</field>
    </element>
    <element>
...