I'm using DOMDocument class of PHP to create a xml file, my code is:
$xmlObject = new DOMDocument('1.0', 'utf-8');
//root node -- books
$books = $xmlObject->createElement('books');
//book node
$book = $xmlObject->createElement('book');
//book node's attribute -- index
$index = new DOMAttr('index', '1');
$book->appendChild($index);
//name node
$name = $xmlObject->createElement('name', 'Maozedong');
//name node's attribute -- year
$year = new DOMAttr('year', '1920');
$name->appendChild($year);
$book->appendChild($name);
//story node
$story = $xmlObject->createElement('story');
$title = $xmlObject->createElement('title', 'Redrevolution');
$quote = $xmlObject->createElement('quote', 'LeaveoffHunan');
$story->appendChild($title);
$story->appendChild($quote);
$book->appendChild($story);
$books->appendChild($book);
if ($xmlObject->save('xml/books.xml') != false){
echo 'success';
}else{
echo 'error';
}
The content of books.xml is only one line:
<?xml version="1.0" encoding="utf-8"?>
the other node is non-existent. Are there any errors in my code?
I forget append the books node to $xmlObject.
add:
$xmlObject->appendChild($books);
Related
I have a PHP code that is running well, however not as expected.
F.Y.I: It´s running a function that is collecting submitted data from a form. (piece of code not included here, cause it´s OK).
I need to have 2 fields inside "Dados": name and email, however only email is being recorded.
What should I do? Any clue?
My actual PHP code:
function my_generate_xml($posted_data)
$domDocument = new DOMDocument('1.0', 'ISO-8859-1');
$domDocument->formatOutput = true;
// build maximizer xml file
$xml_root = $domDocument->createElement('moduledata');
$xmlEntity = $domDocument->createElement('entity');
$xmlEntityTN = $domDocument->createAttribute('tablename');
$xmlEntityTN->value = 'Ent';
$xmlEntityFN = $domDocument->createAttribute('formatname');
$xmlEntityFN->value = 'Curriculum';
$xmlEntity->appendChild($xmlEntityTN);
$xmlEntity->appendChild($xmlEntityFN);
$xmlDefine = $domDocument->createElement('define');
$xmlDefine->nodeValue = $posted_data['nome'];
$xmlDefineN = $domDocument->createAttribute('name');
$xmlDefineN->value = 'ParamNome';
$xmlDefine->appendChild($xmlDefineN);
$xmlEntity->appendChild($xmlDefine);
$xmlSiga = $domDocument->createElement('SigaFiles');
$xmlSigaDN = $domDocument->createAttribute('Text');
$xmlSigaDN->value = 'SQG';
$xmlSiga->appendChild($xmlSigaDN);
// create node for current dados
$xml_dados = $domDocument->createElement('Dados');
$domElement = $domDocument->createElement('attribute',$posted_data['nome']);
$domElement = $domDocument->createElement('attribute',$posted_data['email']);
$domAttribute = $domDocument->createAttribute('domainname');
// Value for the created attribute
$domAttribute->value = 'Nome';
$domAttribute->value = 'Email';
$domElement->appendChild($domAttribute);
$xml_dados->appendChild($domElement);
$xmlSiga->appendChild($xml_dados);
$xmlEntity->appendChild($xmlSiga);
$xml_root->appendChild($xmlEntity);
$domDocument->appendChild($xml_root);
Desired XML output format:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<moduledata>
<entity tablename="Ent" formatname="Curriculum">
<define name="ParamNome">Thomas Edison</define>
<SigaFiles Text="SQG">
<Dados>
<attribute domainname="Nome">Thomas Edison</attribute>
<attribute domainname="Email">thomas.edison#gmail.com</attribute>
</Dados>
</SigaFiles>
</entity>
</moduledata>
Actual XML output format:
<?xml version="1.0" encoding="ISO-8859-1"?>
<moduledata>
<entity tablename="Ent" formatname="Curriculum">
<define name="ParamNome">Thomas Edison</define>
<SigaFiles Text="SQG">
<Dados>
<attribute domainname="Email">thomas.edison#gmail.com</attribute>
</Dados>
</SigaFiles>
</entity>
</moduledata>
Actual XML output format: (UPDATED)
<?xml version="1.0" encoding="ISO-8859-1"?>
<moduledata>
<entity tablename="Ent" formatname="Curriculum">
<define name="Thomas Edison">nome</define>
<SigaFiles Text="SQG">
<Dados>
<attribute domainname="Nome">Thomas Edison</attribute>
<attribute domainname="Email">thomas.edison#gmail.com</attribute>
</Dados>
</SigaFiles>
</entity>
</moduledata>
PHP Code (Updated)
<?php
function my_generate_xml($posted_data)
{
$domDocument = new DOMDocument('1.0', 'ISO-8859-1');
$domDocument->formatOutput = true;
// build maximizer xml file
$xml_root = $domDocument->createElement('moduledata');
$xmlEntity = $domDocument->createElement('entity');
$xmlEntityTN = $domDocument->createAttribute('tablename');
$xmlEntityTN->value = 'Ent';
$xmlEntityFN = $domDocument->createAttribute('formatname');
$xmlEntityFN->value = 'Curriculum';
$xmlEntity->appendChild($xmlEntityTN);
$xmlEntity->appendChild($xmlEntityFN);
$xmlDefine = $domDocument->createElement('define');
$xmlDefine->nodeValue = $posted_data['nome'];
$xmlDefineN = $domDocument->createAttribute('name');
$xmlDefineN->value = 'ParamNome';
$xmlDefine->appendChild($xmlDefineN);
$xmlEntity->appendChild($xmlDefine);
$xmlSiga = $domDocument->createElement('SigaFiles');
$xmlSigaDN = $domDocument->createAttribute('Text');
$xmlSigaDN->value = 'SQG';
$xmlSiga->appendChild($xmlSigaDN);
// create node for current dados
$xml_dados = $xmlSiga->appendChild($domDocument->createElement('Dados'));
$domElement = $xml_dados->appendChild($domDocument->createElement('attribute'));
$domElement->appendChild($domDocument->createTextNode($posted_data['nome']));
$domElement->setAttribute('domainname', 'Nome');
$domElement = $xml_dados->appendChild($domDocument->createElement('attribute'));
$domElement->appendChild($domDocument->createTextNode($posted_data['email']));
$domElement->setAttribute('domainname', 'Email');
$domDocument->appendChild($domElement);
$xmlSiga->appendChild($domDocument);
$xmlEntity->appendChild($xmlSiga);
$xml_root->appendChild($xmlEntity);
$domDocument->appendChild($xml_root);
// save it as a file for further processing
$content = chunk_split(base64_encode($domDocument->saveXML()));
$uploads = wp_upload_dir();
$domDocument->save($uploads['basedir'].'/prorh/'.(int)microtime(true).'.xml');
}
?>
Consider reorganizing your routine and append elements after their creation and not save all appendChild calls at the end. Since you reuse the same variable names keep all components (element, attribute, values) together. Recall XML is a tree structure that grows from the root:
// build maximizer xml file
$domDocument = new DOMDocument('1.0', 'ISO-8859-1');
$domDocument->formatOutput = true;
// moduledata root element
$xml_root = $domDocument->createElement('moduledata');
$domDocument->appendChild($xml_root);
// entity element
$xmlEntity = $domDocument->createElement('entity');
$xml_root->appendChild($xmlEntity);
$xmlEntityTN = $domDocument->createAttribute('tablename');
$xmlEntityTN->value = 'Ent';
$xmlEntityFN = $domDocument->createAttribute('formatname');
$xmlEntityFN->value = 'Curriculum';
$xmlEntity->appendChild($xmlEntityTN);
$xmlEntity->appendChild($xmlEntityFN);
// define element
$xmlDefine = $domDocument->createElement('define');
$xmlEntity->appendChild($xmlDefine);
$xmlDefine->nodeValue = $posted_data['nome'];
$xmlDefineN = $domDocument->createAttribute('name');
$xmlDefineN->value = 'ParamNome';
$xmlDefine->appendChild($xmlDefineN);
// SigaFiles element
$xmlSiga = $domDocument->createElement('SigaFiles');
$xmlEntity->appendChild($xmlSiga);
$xmlSigaDN = $domDocument->createAttribute('Text');
$xmlSigaDN->value = 'SQG';
$xmlSiga->appendChild($xmlSigaDN);
// dados element
$xml_dados = $domDocument->createElement('Dados');
$xmlSiga->appendChild($xml_dados);
// attribute child nodes
$domElement = $domDocument->createElement('attribute', $posted_data['nome']);
$domAttribute = $domDocument->createAttribute('domainname');
$domAttribute->value = 'Nome';
$domElement->appendChild($domAttribute);
$xml_dados->appendChild($domElement);
$domElement = $domDocument->createElement('attribute', $posted_data['email']);
$domAttribute = $domDocument->createAttribute('domainname');
$domAttribute->value = 'Email';
$domElement->appendChild($domAttribute);
$xml_dados->appendChild($domElement);
// OUTPUT TREE TO STRING
header("Content-type: text/xml");
echo $domDocument->saveXML();
You override the $domElement variable without appending the node.
// create node for current dados
$xml_dados = $domDocument->createElement('Dados');
$domElement = $domDocument->createElement('attribute',$posted_data['nome']);
$domElement = $domDocument->createElement('attribute',$posted_data['email']);
$domAttribute = $domDocument->createAttribute('domainname');
I suggest nesting the create* calls inside appendChild() calls.
// create node for current dados
$xml_dados = $xmlSiga->appendChild($domDocument->createElement('Dados'));
$domElement = $xml_dados->appendChild($domDocument->createElement('attribute'));
$domElement->appendChild($domDocument->createTextNode($posted_data['nome']));
$domElement->setAttribute('domainname', 'Nome');
$domElement = $xml_dados->appendChild($domDocument->createElement('attribute'));
$domElement->appendChild($domDocument->createTextNode($posted_data['email']));
$domElement->setAttribute('domainname', 'Email');
You do not need to create attributes as nodes, DOMElement::setAttribute() works just fine for that. But you should create text content as nodes. The second argument of DOMDocument::createElement() is broken and escapes only some special characters.
i want to replace value of commented tags in xml file..how can i replace it using php ..given is file.xml
<SyncOpportunity_Input>
<SendConfirmationEmail/>
<UpdateToken/>
<CallingSystem>WS-TEST</CallingSystem>
<KeepLocking/>
<Error_spcCode/>
<EmailAddrOverwrite/>
<Opportunity>
//<IntegrationId>12</IntegrationId>
//<LoanWriterId>13</LoanWriterId>
//<Description>NA</Description>
<Applicant>
<integratedid1>28</integratedid1>
<FirstName>pri</FirstName>
<LastName>kj</LastName>
</Applicant>
<Property>
<integratedid>2</integratedid>
<Title>Mr</Title>
<DateOfBirth>1999-11-11</DateOfBirth>
</Property>
<Ownership>
<integratedid1>28</integratedid1>
<OwnershipPercentage>100</OwnershipPercentage>
</Ownership>
</Opportunity>
</SyncOpportunity_Input>
i dont want to create node each time.. i just want to replace the value of child node..as i am appending other tags dynamically using php.
here is my function.php file where I have appended other tags,where i have get tags and then created child nodes and the value of each tags is coming from our php form.As well each time we require to delete previous data.
$xml = new DOMDocument('1.0', 'utf-8');
$xml->formatOutput = true;
$xml->preserveWhiteSpace = false;
$nodesToDelete=array();
$pnodesToDelete=array();
//echo $fname;
$xml->load('file.xml');
$nodesToDelete=array();
$IntegrationId = rand(1,19);
$IntegrationId1 = rand(10,30);
$IntegrationId2 = rand(20,40);
$element = $xml->getElementsByTagName('Applicant')->item(0);
$pelement = $xml->getElementsByTagName('Property')->item(0);
$FirstName = $element->getElementsByTagName('FirstName')->item(0);
$LastName = $element->getElementsByTagName('LastName')->item(0);
//echo $timestamp;
//$oelement = $xml->getElementsByTagName('Opportunity');
$oelement = $xml->getElementsByTagName('Ownership')->item(0);;
$ownItem= $xml->createElement('Ownership');
$ownItem->appendChild($xml->createElement('integratedid1',$IntegrationId1 ));
$ownItem->appendChild($xml->createElement('OwnershipPercentage',100));
//$oItem->appendChild($xml->createElement('integratedid2',$IntegrationId2));
$newItem= $xml->createElement('Applicant');
$newItem->appendChild($xml->createElement('integratedid1',$IntegrationId1 ));
$newItem->appendChild($xml->createElement('FirstName', $_POST['fld_2260636']));
$newItem->appendChild($xml->createElement('LastName', $_POST['fld_4322743']));
$pnewItem= $xml->createElement('Property');
$pnewItem->appendChild($xml->createElement('integratedid',$IntegrationId ));
$pnewItem->appendChild($xml->createElement('Title', $_POST['fld_4755553']));
$pnewItem->appendChild($xml->createElement('DateOfBirth', $_POST['fld_1151367']));
//echo $newItem;
$xml->getElementsByTagName('Opportunity')->item(0)->appendChild($newItem);
$xml->getElementsByTagName('Opportunity')->item(0)->appendChild($pnewItem);
$xml->getElementsByTagName('Opportunity')->item(0)->appendChild($ownItem);
$nodesToDelete[]=$element;
$pnodesToDelete[]=$pelement;
$onodesToDelete[]=$oelement;
I do not understand these node value things at all i am trying to replicate an xml design in php but having quite a bit of trouble the file i am trying to reproduce through php is.
<items>
<item>
<id></id>
<name></name>
<price></price>
<quantity></quantity>
<description></description>
<qonhold></qonhold>
<qsold></qsold>
</item>
</items>
And the PHP file to recreate this is almost all done
$dom = new DOMDocument("1.0");
// create root element
$root = $dom->createElement("Items");
$dom->appendChild($root);
$dom->formatOutput=true;
// create child element
$item = $dom->createElement("item");
$dom->appendChild($item);
// create text node
$id = $dom->createElement("id");
$root->appendChild($id);
$name = $dom->createElement("name");
$root->appendChild($name);
$price = $dom->createElement("price");
$root->appendChild($price);
$quantity = $dom->createElement("quantity");
$root->appendChild($quantity);
$description = $dom->createElement("description");
$root->appendChild($description);
$qonhold = $dom->createElement("qonhold");
$root->appendChild($qonhold);
$qsold = $dom->createElement("qsold");
$root->appendChild($qsold);
The problem i am having is its saving it all under "items" being the root.. but i can not get everything id, name, price, quantity, description, qonhold, qsold to save under just "item" which is saved under "items
You should use ->appendChild() on the item node created, not the root which is <items>:
// create child element
$item = $dom->createElement("item");
$dom->appendChild($item);
// create text node
$id = $dom->createElement("id");
$item->appendChild($id); // item->appendChild not $root->appendChild
Should look like this:
$dom = new DOMDocument("1.0");
// create root element
$root = $dom->createElement("Items");
$dom->appendChild($root);
$dom->formatOutput=true;
// create child element
$item = $dom->createElement("item");
$root->appendChild($item); // append to `<Items>`
// create text node
$id = $dom->createElement("id");
$item->appendChild($id); // append to `<item>`
$name = $dom->createElement("name");
$item->appendChild($name); // append to `<item>`
$price = $dom->createElement("price");
$item->appendChild($price); // append to `<item>`
$quantity = $dom->createElement("quantity");
$item->appendChild($quantity); // append to `<item>`
$description = $dom->createElement("description");
$item->appendChild($description); // append to `<item>`
$qonhold = $dom->createElement("qonhold");
$item->appendChild($qonhold); // append to `<item>`
$qsold = $dom->createElement("qsold");
$item->appendChild($qsold); // append to `<item>`
I am creating PHP system for edit XML files to translation of game.
I am using DOM e.g for file-comparision for translators (with update XML file).
I have old and new XML (in advance: I can not change XML structure) with new strings and/or new IDs.
For future echo node value to comparision by the same ID order, I have following code:
<?php
$xml2 = new DOMDocument('1.0', 'utf-16');
$xml2->formatOutput = true;
$xml2->preserveWhiteSpace = false;
$xml2->load(substr($file, 0, -4).'-pl.xml');
$xml = new DOMDocument('1.0', 'utf-16');
$xml->formatOutput = true;
$xml->preserveWhiteSpace = false;
$xml->load($file);
for ($i = 0; $i < $xml->getElementsByTagName('string')->length; $i++) {
if ($xml2->getElementsByTagName('string')->item($i)) {
$element_pl = $xml2->getElementsByTagName('string')->item($i);
$body_pl = $element_pl->getElementsByTagName('body')->item(0);
$id_pl = $element_pl->getElementsByTagName('id')->item(0);
} else $id_pl->nodeValue = "";
$element = $xml->getElementsByTagName('string')->item($i);
$id = $element->getElementsByTagName('id')->item(0);
$body = $element->getElementsByTagName('body')->item(0);
if ($id_pl->nodeValue == $id->nodeValue) {
$element->appendChild( $xml->createElement('body-pl', $body_pl->nodeValue) );
}
}
$xml = simplexml_import_dom($xml);
?>
Above code change:
<?xml version="1.0" encoding="utf-16"?>
<strings>
<string>
<id>1</id>
<name>ABC</name>
<body>English text</body>
</string>
</strings>
to (by adding text from *-pl.xml file):
<?xml version="1.0" encoding="utf-16"?>
<strings>
<string>
<id>1</id>
<name>ABC</name>
<body>English text</body>
<body-pl>Polish text</body-pl>
</string>
</strings>
But I need find "body" value in *-pl.xml by "name" value.
"For" loop:
get "ABC" from "name" tag [*.xml] ->
find "ABC" in "name" tag [*-pl.xml] ->
get body node from that "string" [*-pl.xml]
I can do that by strpos(), but my (the smallest) file have 25346 lines..
Is there something to do e.g. "has children ("name", "ABC") -> parent" ?
Then I can get "body" value of this string.
Thank you in advance for suggestions or link to similar, resolved ask,
Greetings
You need XPath expressions:
//name[text()='ABC']/../body
or
//name[text()='ABC']/following-sibling::body
Check the PHP manual for DOMXPath class and its query method. In a nutshell, you'd use it like this:
$xpath = new DOMXPath($dom_document);
// find all `body` nodes that have a `name` sibling
// with an `ABC` value in the entire document
$nodes = $xpath->query("//name[text()='ABC']/../body");
foreach($nodes as $node) {
echo $node->textContent , "\n\n";
}
I am creating xml file as below, can anybody help how to get that using php?
xml file:
<products>
<product id="123" />
</products>
Php file:
i am using following code but not getting result as above
$xml = new DomDocument('1.0', 'utf-8');
$xml->formatOutput = true;
$products= $xml->createElement('products');
$product = $xml->createElement('product');
$id = $xml->createElement('id');
$xml->appendChild($products);
$products->appendChild($product);
$product->appendChild($id);
$id->nodeValue = 123;
$xml->save("data.xml");
retrieving xml data:
$xml = new DomDocument();
$xmlFile = "data.xml";
$xml= DOMDocument::load($xmlFile);
$product = $xml->getElementsByTagName("product");
foreach($product as $node)
{
$address = $node->getElementsByAttributeName("address");
$address = $address->item(0)->nodeValue;
echo"$address";
}
You are not getting the results you want because you're adding id as a tag rather than an attribute. I just refactored your code a little and made id an attribute. I tested the code below and it produces your desired result.
<?php
$xml = new DomDocument('1.0', 'utf-8');
$xml->formatOutput = true;
$products= $xml->createElement('products');
$product = $xml->createElement('product');
$xml->appendChild($products);
$products->appendChild($product);
$product->appendChild(new DomAttr('id', '123'));
$xml->save("data.xml");
?>
If id is to be an attribute, then you need to use the DOMElement::setAttribute() method. I think this will work - according to the documentation, if an attribute doesn't already exist it will be created.
$product->setAttribute("id", "123");
Then loas the $product->appendChild( $id );