i'm trying to manipulate an xml by adding a few custom tags.
I managed to add a custom Element and a TextNode on it, but it gets rendered at the very bottom of the XML.
How do i add this custom tag as a child of another tag? i tried using the following code:
$product_record = $xml->documentElement->getElementsByTagName('product_record');
and then
$text = $test->appendChild($product_record);
But it doesn't seem to be working.
Here's where i got stuck:
http://viper-7.com/CsRNHU
How do i get the test tag to be rendered inside product_record?
Thanks,
Thales
Taking your full example you add the new element to the document itselt, not the fetched node.
The getElementsByTagName() method returns a list of nodes, not a single node, so you need to use a loop or fetch a specific element from the list.
$xml = new DOMDocument();
$xml->load($url);
$products = $xml->documentElement->getElementsByTagName('product_record');
foreach ($products as $product) {
$test = $product
->appendChild($xml->createElement('test'))
->appendChild($xml->createTextNode("testing"));
}
echo $xml->saveXML();
The DOMDocument::create*() methods create specific nodes and return them. The appendChild() method adds it to a parent node and returns the added node.
Your example returns an UTF-16 encoded XML. Import it into an UTF-8 XML document if you want to change the encoding:
$utf8 = new DOMDocument('1.0', 'UTF-8');
$utf8->appendChild($utf8->importNode($xml->documentElement, TRUE));
Demo: http://viper-7.com/1eCPeo
Related
I am using PHP DOMDocument() to generate XML file with elements.
I am appending all details into sample xml file into components tag. But closing tag is not coming. I want to create closing tag.
My Code is doing this
<component expiresOn="2022-12-31" id="pam" />
I want to do like following
<component expiresOn="2022-12-31" id="pam"></component>
My PHP CODE SAMPLE
$dom = new DOMDocument();
$dom->load("Config.xml");
$components = $dom->getElementsByTagName('components')->item(0);
if(!empty($_POST["pam"])) {
$pam = $_POST["pam"];
$component = $dom->createElement('component');
$component->setAttribute('expiresOn', $expirydate);
$component->setAttribute('id', "pam");
$components->appendChild($component5);
}
$dom->save("Config.xml");
I tested following suggestion and its not working. Both xml-php code are different.
$dom->saveXml($dom,LIBXML_NOEMPTYTAG);
Self-closing tags using createElement
I tested following.
You're trying to use DOMDocument::saveXML to save the new XML back into the original file, but all that function does is return the XML as a string. Since you aren't assigning the result to anything, nothing happens.
If you want to save the XML back to your file, as well as avoiding self-closing tags, you'll need to use the save method as you originally were, and also pass the option:
$dom->save('licenceConfig.xml', LIBXML_NOEMPTYTAG);
See https://3v4l.org/e6N5s for a demo
if you do in php:
$dom = new DOMDocument();
$dom->loadHTML($pageUrl);
$dom->getElementById(eleId);
How can you hide the element. I know how you can do it with css and js. But I want to know it with php.
I’m going to assume that you’re trying to have the element initially hidden i.e. in existence, but not visible, upon the browser’s initial rendering and you already know that PHP can’t directly instruct the browser to hide elements.
Following your example, you could do:
$eleId = “div_to_hide”;
$dom = new DOMDocument();
$dom->loadHTML($pageUrl);
$target_elem = $dom->getElementById($eleId);
if ($target_elem) {
$target_elem-> setAttribute('style','display: none;');
}
Or you could create a “script” element containing JavaScript code to execute after the resource has totally downloaded to hide it at run-time.
Or you could create a “style” element in your DOMDocument object in which you’d put CSS content referencing the target element (by selector) to apply initial “display: none;” CSS.
Just other ideas, but the snippet above follows your paradigm.
I want to get all organic search results from Google.
I need help defining the XPath to exclude the ads. The cite tag on the ads does not contain a class attribute, and the organic results have 2 different class values. My attempts at defining the XPath have failed. The Google results page looks something like this
Ad
<cite>example.com</cite>
Organic Result 1
<cite class="_Rm">example.com/page1.html</cite>
Organic Result 2
<cite class="_Rm bc">example.com > Breadcrumbs > Page2</cite>
Here is my code:
$html = new DOMDocument();
#$html->loadHtmlFile('http://www.google.com/search?q=mortgage&num=100');
$xpath = new DOMXPath($html);
$nodes = $xpath->query('//cite');
foreach ($nodes as $n){
echo $n->nodeValue.'<br />'; // Show all links
}
Please help
Try //cite[#class='_Rm' or #class='_Rm bc'] This will select cite nodes with a class that is either _Rm or _RM bc.
Assuming the portion of the HTML you want to get is not generated by client-side scripts (usually javascript), following simple XPath will do the job :
$nodes = $xpath->query('//cite[#class]');
Above XPath gets all <cite> tags containing class attribute with any value.
Otherwise, you need to find a way to run the client-side scripts, so that the HTML can be generated completely before you can apply above XPath query against the HTML.
I need to add classes to the navigation HTML being output from a function in a custom CMS.
The only way I can get the output I need is to parse the HTML with PHP.
I am using PHP's DOM methods to look through the HTML and add a class to any <li> element that contains a child <ul> (top level navigation items).
So far it's working, but I have 2 questions:
Is there a more efficient way for me to go through this DOM data? It seems cumbersome to me, but that could just be my lack of experience.
In some cases, my <li> elements may already have a class, how can I add to the existing class attribute without destroying what may or may not already be there?
-
<?
$mcms_nav = getContent(
// call to cms that returns navigation html as a string
// ex. <ul id="pnav"><li>home</li>....</ul>
);
$dom = new DOMDocument();
$dom->preserveWhiteSpace = FALSE;
$dom->loadHTML($mcms_nav);
$x = new DOMXPath($dom);
foreach($x->query('//ul/li/ul') as $node)
{
$parent = $node->parentNode;
$parent_attr = $dom->createAttribute('class');
$parent_attr->value = 'has-flyout';
$parent->appendChild($parent_attr);
$flyout_attr = $dom->createAttribute('class');
$flyout_attr->value = 'flyout';
$node->appendChild($flyout_attr);
}
$mcms_nav = $dom->getElementByID('pnav');
echo $dom->saveHTML($mcms_nav);
?>
Not really. You could take the XML class from the CakePHP framework, turn this into an array, manipulate the array, and turn it back. Not sure if that's an option in your case. http://book.cakephp.org/2.0/en/core-utility-libraries/xml.html
You can use dom->hasAttribute() and dom->getAttribute() to get the existing attribute contents if they exist.
Also, a new job wouldn't hurt ;)
How can I (with PHP) remove the style attributes from DIVS having a certain class?
Because of an 'Drag&Drop' process some DIV elements get polluted with unnecessary styles which can lead to problems later on.
I know I can remove the style attributes with JavaScript after a 'Drag&Drop' process, but I only remove them when to HTML is being processed by the server (For sending the HTML as an e-mail).
This isn't a particularly difficult problem, so far as I can tell. You need to load the HTML into a DOMDocument structure, then use a simple XPath attribute selector to find the relevant elements and DOMElement::removeAttribute to remove the style attribute. Your code might look like this:
$dom = new DOMDocument;
$dom->loadHTML($dirtyHtml);
$xpath = new DOMXPath($dom);
$divs = $xpath->query('//div[#class="someclass"]');
foreach ($divs as $div) {
$div->removeAttribute('style');
}
$cleanHtml = $dom->saveHTML();