I have a basic XML file that contains the following data:
<?xml version="1.0"?>
<rosters id_parent_provider="928" upload_key="8257QP01">
<roster>
<id_provider>928</id_provider>
<provider_course_code>2022 - Medical Errors</provider_course_code>
<id_course>895456</id_course>
<id_publishing></id_publishing>
<end_date></end_date>
<attendees>
<attendee>
<licensee_profession>AAA</licensee_profession>
<licensee_number>BBB123</licensee_number>
<first_name></first_name>
<last_name></last_name>
<cebroker_state>CC</cebroker_state>
<date_completed>DD-DD-DDDD</date_completed>
<ce_credit_hours>E</ce_credit_hours>
</attendee>
</attendees>
</roster>
</rosters>
I load the file in using:
$xml_string = file_get_contents($test_file);
$roster = simplexml_load_string($xml_string);
and then roster contains the following upon var_dump:
object(SimpleXMLElement)#4 (2) { ["@attributes"]=> array(2) { ["id_parent_provider"]=> string(3) "928" ["upload_key"]=> string(8) "8257QP01" } ["roster"]=> object(SimpleXMLElement)#5 (6) { ["id_provider"]=> string(3) "928" ["provider_course_code"]=> object(SimpleXMLElement)#6 (0) { } ["id_course"]=> string(6) "895456" ["id_publishing"]=> object(SimpleXMLElement)#7 (0) { } ["end_date"]=> object(SimpleXMLElement)#8 (0) { } ["attendees"]=> object(SimpleXMLElement)#9 (1) { ["attendee"]=> object(SimpleXMLElement)#10 (7) { ["licensee_profession"]=> string(3) "AAA" ["licensee_number"]=> string(7) "BBB1234" ["first_name"]=> object(SimpleXMLElement)#11 (0) { } ["last_name"]=> object(SimpleXMLElement)#12 (0) { } ["cebroker_state"]=> string(2) "CC" object(SimpleXMLElement)#13 (0) { } ["date_completed"]=> string(10) "DD-DD-DDDD" ["ce_credit_hours"]=> string(1) "E" } } } }
I need to replace text AAA, BB1234, CC, DD-DD-DDDD and E with values I have stored in my website's database. How do I access the appropriate nodes and then change the value. I have tried following several simpleXMLElement tutorials, but not sure what i am doing wrong.
CodePudding user response:
I imagine there are more elegant ways to do this, but one quick way would be this:
$replacements = ["former AAA","former BB1234","former CC","former DD-DD-DDDD","former E"];
$attendees = $roster->xpath("//attendees");
foreach ($attendees as $attendee) {
$lp = ($attendee->xpath('.//licensee_profession'));
$lp[0][0]=$replacements[0];
$ln = ($attendee->xpath('.//licensee_number'));
$ln[0][0]=$replacements[1];
$ce = ($attendee->xpath('.//cebroker_state'));
$ce[0][0]=$replacements[2];
$dc = ($attendee->xpath('.//date_completed'));
$dc[0][0]=$replacements[3];
$cch = ($attendee->xpath('.//ce_credit_hours'));
$cch[0][0]=$replacements[4];
}
echo $roster->asXml();
Output:
<?xml version="1.0"?>
<rosters id_parent_provider="928" upload_key="8257QP01">
<roster>
<id_provider>928</id_provider>
<provider_course_code>2022 - Medical Errors</provider_course_code>
<id_course>895456</id_course>
<id_publishing/>
<end_date/>
<attendees>
<attendee>
<licensee_profession>former AAA</licensee_profession>
<licensee_number>former BB1234</licensee_number>
<first_name/>
<last_name/>
<cebroker_state>former CC</cebroker_state>
<date_completed>former DD-DD-DDDD</date_completed>
<ce_credit_hours>former E</ce_credit_hours>
</attendee>
</attendees>
</roster>
</rosters>
CodePudding user response:
Consider using parameterized XSLT (special-purpose language designed to transform XML files) which PHP can pass into using the DOMDocument class to update needed node text values.
XSLT (save as .xsl file)
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- DEFINE PARAMS -->
<xsl:param name="lp_param"/>
<xsl:param name="ln_param"/>
<xsl:param name="cs_param"/>
<xsl:param name="dc_param"/>
<xsl:param name="ce_param"/>
<!-- IDENTITY TRANSFORM -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<!-- UPDATE NODES BY PARAM VALUE -->
<xsl:template match="attendee">
<xsl:copy>
<licensee_profession><xsl:value-of select="$lp_param"/></licensee_profession>
<licensee_number><xsl:value-of select="$ln_param"/></licensee_number>
<xsl:apply-templates select="first_name|last_name"/>
<cebroker_state><xsl:value-of select="$cs_param"/></cebroker_state>
<date_completed><xsl:value-of select="$dc_param"/></date_completed>
<ce_credit_hours><xsl:value-of select="$ce_param"/></ce_credit_hours>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
PHP
// LOAD XML
$xml = new DOMDocument('1.0', 'UTF-8');
$xml->load("input.xml");
// LOAD XSLT
$xsl = new DOMDocument('1.0', 'UTF-8');
$xsl->load("xslt_script.xsl");
// INITIALIZE TRANSFORMER
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);
// SET PARAMETER VALUES
$proc->setParameter('', 'lp_param', $licensee_profession);
$proc->setParameter('', 'ln_param', $licensee_number);
$proc->setParameter('', 'cs_param', $cebroker_state);
$proc->setParameter('', 'dc_param', $date_completed);
$proc->setParameter('', 'ce_param', $ce_credit_hours);
// TRANSFORM SOURCE
$new_xml = $proc->transformToDoc($xml);
// ECHO TO SCREEN
echo $new_xml->saveXML();
// SAVE TO FILE
file_put_contents("output.xml", $new_xml);