Note that there are some explanatory texts on larger screens.

plurals
  1. POThe Curse of XML and PHP Whitespace
    primarykey
    data
    text
    <p>I am having an issue with DOMDocument and whitespace. Currently I have two types of XML files. One file was created manually about a year ago, I will call this file A. The second file, file B, is being generated using a PHP DOMDocument. I have been trying very hard (unsuccessfully) to make the whitespace in file A match file B. </p> <p>Here's how it works... The user is given an option to add new <code>&lt;Slide&gt;</code> elements to the XML file. After new slides have been added the user has the option to add new <code>&lt;Items&gt;</code> to the XML file as a child of the <code>&lt;Slide&gt;</code> element.</p> <p>When I add a <code>&lt;Slide&gt;</code> element to file B it works like a charm. I can even add a new <code>&lt;Item&gt;</code> element with zero problem. However, when I try to access the new <code>&lt;Identifier&gt;</code> element I just added in file B using the second PHP script below with <code>$order != 'remove'</code> I miss the node by one and select <code>&lt;Information/&gt;</code> instead. </p> <p><em>It appears that manually created file A has white space that is not present in my generated file B. I have experimented with the preserveWhitespace property but it did not help.</em> </p> <p><strong>Are there any suggestions on how I can correct this problem. Constructive criticism is also welcome as this is my first shot at dynamic XML manipulation. I apologize for the length and appreciate your time!!</strong> </p> <p>File A - Created Manually - I am trying to match this file!</p> <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;root&gt; &lt;Areas&gt;Head &amp;amp; Neck&lt;/Areas&gt; &lt;Area&gt;Head &amp;amp; Neck&lt;/Area&gt; &lt;Type&gt;Angiograph&lt;/Type&gt; &lt;Slide&gt;Ag-01a &lt;Title&gt;Catheter Angiography&lt;/Title&gt; &lt;Item1&gt; &lt;Identifier interestCoord=".51,.73" locator="point" labelBool="true" labelTxt="" leaderBool="true"&gt;Aortic Arch &lt;/Identifier&gt; &lt;Information/&gt; &lt;Question A="" B="" C="" D="" E="" Answer=""/&gt; &lt;/Item1&gt; .... More Items </code></pre> <p>File B - Before user adds <code>&lt;Slide&gt;</code>. This portion is created Manually. A <em>template</em> if you will. After the user enters slide names new slides are generated using the chunk of code below. </p> <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;root&gt; &lt;Areas&gt;Head &amp;amp; Neck&lt;/Areas&gt; &lt;Area&gt;Head &amp;amp; Neck&lt;/Area&gt; &lt;Type&gt;Brain Sections&lt;/Type&gt; &lt;/root&gt; </code></pre> <p>File B - After users adds new <code>&lt;Slide&gt;</code> and <code>&lt;Item&gt;</code>. Formatting shown represents formatting created by DOMDocument. <strong><em>I think this is where the error is occuring! Whitespace!!!</em></strong></p> <pre><code>&lt;Slide&gt;Ag-09a &lt;Title&gt;Catheter Angiography&lt;/Title&gt; &lt;Item1&gt;&lt;Identifier locator="point" interestCoord="0.143,0.65" labelBool="true" labelTxt="" leaderBool="false"&gt;Orbit&lt;/Identifier&gt;&lt;Information/&gt;&lt;Question A="" B="" C="" D="" E="" Answer=""/&gt;&lt;/Item1&gt;&lt;/Slide&gt; </code></pre> <p>PHP script used to add new <code>&lt;Slide&gt;</code> elements to XML</p> <pre><code>&lt;?php session_start(); //Constants $SECTION_SEP = "========================================================================&lt;/br&gt;"; //Variables used to construct file path $area = trim($_POST['area']); $slideType = trim($_POST['slideType']); $rawSlides = trim($_POST['theseSlides']); $newSlideList = explode(",", $rawSlides); $fileLocation = "../XML/".$area."/".$slideType."/".$area.".XML"; $dom = new DOMDocument(); echo('New DOMDocument created!&lt;/br&gt;'); $dom-&gt;load($fileLocation); echo('XML file loaded!&lt;/br&gt;'); /*$dom-&gt;preserveWhiteSpace = false; echo('White space removed!&lt;/br&gt;');*/ $dom-&gt;documentElement; echo('DOM initialized!&lt;/br&gt;'); if ($dom-&gt;getElementsByTagName('Slide')-&gt;length == 0){ //New file with no slides foreach ($newSlideList as $slide){ $newSlide = $dom-&gt;createElement('Slide', $slide); $newTitle = $dom-&gt;createElement('Title', 'Scan'); //Add the title element to the Item $newSlide-&gt;appendChild($newTitle); $dom-&gt;childNodes-&gt;item(0)-&gt;appendChild($newSlide); echo($slide." has been added to the list!&lt;/br&gt;"); } } else { $locators = $dom-&gt;getElementsByTagName('Slide'); } if($dom-&gt;save($fileLocation)){ echo("File saved successfully!!"); }else echo("There was a problem saving the file!"); </code></pre> <p>PHP script used to add/edit/remove <code>&lt;Item&gt;</code> and <code>&lt;Identifier&gt;</code> nodes depending on value of <code>$orders</code> == WARNING! Lengthy :/</p> <pre><code>&lt;?php session_start(); //Constants $SECTION_SEP = "========================================================================&lt;/br&gt;"; //Variables used to construct file path $area = trim($_POST['area']); $slideType = trim($_POST['slideType']); $fileLocation = "../XML/".$area."/".$slideType."/".$area.".XML"; //echo("File location:".$fileLocation); //Current data (c_ for current) $c_poi = ""; $c_type = ""; $c_lblBool = ""; $c_lblOverride = ""; $c_leaderBool = ""; //Determine if this visit is for new or old data $orders = trim($_POST['orders']); //Variables used to replace information in XML file loaded below (n_ for new) $n_slideName = trim($_POST['slideName']); //slide name in view format ie Ag-01a $n_identName = trim($_POST['ident']); //contains multiple information separated by comma ie 0,Aortic Arch $n_type = trim($_POST['type']); //locator type $n_poi = trim($_POST['poi']); $n_lblBool = trim($_POST['lblBool']); $n_lblOverride = trim($_POST['lblOverride']); echo("Modified: ".date('c')."&lt;/br&gt;"); $dom = new DOMDocument(); echo('New DOMDocument created!&lt;/br&gt;'); $dom-&gt;load($fileLocation); echo('XML file loaded!&lt;/br&gt;'); /*$dom-&gt;preserveWhiteSpace = false; echo('White space removed!&lt;/br&gt;');*/ $dom-&gt;documentElement; echo('DOM initialized!&lt;/br&gt;'); $locators = $dom-&gt;getElementsByTagName('Slide'); echo($locators-&gt;length.' elements retrieved&lt;/br&gt;'); $slideEntryFound = false; $identEntryFound = false; $identAttributesFound = false; echo($SECTION_SEP); //Locate the correct slide node foreach ($locators as $locator){ //If there is a match, store the infomation // rawSlide[x].childNode[0].nodeValue if(strcmp(trim($locator-&gt;childNodes-&gt;item(0)-&gt;nodeValue),$n_slideName) == 0){ $slideEntryFound = true; $slideChildren = $locator-&gt;childNodes; //Locate the correct identifier node foreach($slideChildren as $child){ if( strcmp(trim($child-&gt;nodeValue), substr($n_identName,strpos($n_identName,",")+1)) == 0){ $identEntryFound = true; if (strcmp($orders, "remove") == 0){//Removing an element echo("The identifier being removed is: ".trim($child-&gt;nodeValue."&lt;/br&gt;")); echo("The node path is: ".($child-&gt;childNodes-&gt;item(1)-&gt;getNodePath())."&lt;/br&gt;"); echo($SECTION_SEP); $locator-&gt;removeChild($child); echo("Identifier successfully removed!&lt;/br&gt;"); echo($SECTION_SEP); break; } else {//Not removing anything - Adding or Editing echo("The identifier being modified is: ".trim($child-&gt;nodeValue."&lt;/br&gt;")); echo("The node path is: ".($child-&gt;childNodes-&gt;item(1)-&gt;getNodePath())."&lt;/br&gt;"); echo($SECTION_SEP); if($child-&gt;childNodes-&gt;item(1)-&gt;hasAttributes()){ $identAttributesFound = true; $c_poi = $child-&gt;childNodes-&gt;item(1)-&gt;getAttribute('interestCoord'); echo("--Current interestCoord: ".$c_poi."&lt;/br&gt;"); echo("++New interestCoord: ".$n_poi."&lt;/br&gt;"); if(strcmp($c_poi, $n_poi) != 0){ $child-&gt;childNodes-&gt;item(1)-&gt;setAttribute('interestCoord',$n_poi); } $c_type = $child-&gt;childNodes-&gt;item(1)-&gt;getAttribute('locator'); echo("--Current locator: ".$c_type."&lt;/br&gt;"); echo("++New locator: ".$n_type."&lt;/br&gt;"); $c_lblBool = $child-&gt;childNodes-&gt;item(1)-&gt;getAttribute('labelBool'); echo("--Current labelBool: ".$c_lblBool."&lt;/br&gt;"); //echo("++New labelBool: ".$n_lblBool."&lt;/br&gt;"); $c_lblOverride = $child-&gt;childNodes-&gt;item(1)-&gt;getAttribute('labelTxt'); echo("--Current labelOverride: ".$c_lblOverride."&lt;/br&gt;"); echo("++New labelOverride: ".$n_lblOverride."&lt;/br&gt;"); $c_leaderBool = $child-&gt;childNodes-&gt;item(1)-&gt;getAttribute('leaderBool'); echo("--Current leaderBool: ".$c_leaderBool."&lt;/br&gt;"); //echo("++New leaderBool: ".$n_leaderBool."&lt;/br&gt;"); if($n_lblOverride != ""){ echo("**A new label override was detected. The identifier will have the alias ".$n_lblOverride."."); } break; } else echo("Fatal Error - Node does not contain attributes!&lt;/br&gt;"); if($identEntryFound == true &amp;&amp; $identAttributesFound == false) echo("Error - Attribute entry not found!"); break; } } } if($slideEntryFound == true &amp;&amp; $identEntryFound == false &amp;&amp; $orders != "remove"){ echo("The identifier was not found... creating a new identifier!&lt;/br&gt;"); //Create a new Element $newElement = $dom-&gt;createElement("Item".((integer)(substr($n_identName,0,strpos($n_identName,",")))+1)); echo("New element created!!&lt;/br&gt;"); //Create new Item children $newSubElem = $dom-&gt;createElement("Identifier", substr($n_identName,strpos($n_identName,",")+1)); $newSubElem-&gt;setAttribute('locator',$n_type); $newSubElem -&gt;setAttribute('interestCoord',$n_poi); $newSubElem-&gt;setAttribute('labelBool', $n_lblBool); $newSubElem-&gt;setAttribute('labelTxt', $n_lblOverride); //TODO link this next one to a variable instead of hard coding $newSubElem-&gt;setAttribute('leaderBool', "false"); //Info Child $newInfoElem = $dom-&gt;createElement("Information"); //Question Child $newQuestion = $dom-&gt;createElement("Question"); $newQuestion-&gt;setAttribute('A', ""); $newQuestion-&gt;setAttribute('B', ""); $newQuestion-&gt;setAttribute('C', ""); $newQuestion-&gt;setAttribute('D', ""); $newQuestion-&gt;setAttribute('E', ""); $newQuestion-&gt;setAttribute('Answer', ""); //Add new children to main Item $newElement-&gt;appendChild($newSubElem); $newElement-&gt;appendChild($newInfoElem); $newElement-&gt;appendChild($newQuestion); $locator-&gt;appendChild($newElement); echo("New identifier added!!&lt;/br&gt;"); break; } } else { } } if($slideEntryFound == false) echo("Error - Slide entry not found!"); if($dom-&gt;save($fileLocation)){ echo("File saved successfully!!"); echo('&lt;div id="phpHandleBtns&gt;"&gt;&lt;/br&gt;&lt;form&gt;&lt;button type="submit" id="continueEdit" formaction="../edit.php"&gt;Continue Editing&lt;/button&gt;'. '&lt;/br&gt;&lt;button type="submit" id="doneEdit" formaction="../main.php"&gt;Done Editing&lt;/button&gt;&lt;/form&gt;&lt;/div&gt;'); }else echo("There was a problem saving the file!"); ?&gt; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload