RunawayPhish RunawayPhish - 3 months ago 13
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

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>
...
Comments