How to replace the text of a node using DOMDocument
Set DOMNode::$nodeValue
instead:
$doc->getElementsByTagName("title")->item(0)->nodeValue = $titleText;
$doc->getElementsByTagName("description")->item(0)->nodeValue = $descriptionText;
$doc->getElementsByTagName("link")->item(0)->nodeValue = $linkText;
This overwrites the existing content with the new value.
PHP DomDocument - How to replace a text from a Node with another node
Xpath allows you to fetch the text nodes containing the string from the document. Then you have to split it into a list of text and element (xref) nodes and insert that nodes before the text node. Last remove the original text node.
$xml = <<<'XML'
<p>
This is a test node with Figure 1.
</p>
XML;
$string = 'Figure 1';
$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXpath($dom);
// find text nodes that contain the string
$nodes = $xpath->evaluate('//text()[contains(., "'.$string.'")]');
foreach ($nodes as $node) {
// explode the text at the string
$parts = explode($string, $node->nodeValue);
// add a new text node with the first part
$node->parentNode->insertBefore(
$dom->createTextNode(
// fetch and remove the first part from the list
array_shift($parts)
),
$node
);
// if here are more then one part
foreach ($parts as $part) {
// add a xref before it
$node->parentNode->insertBefore(
$xref = $dom->createElement('xref'),
$node
);
// with the string that we used to split the text
$xref->appendChild($dom->createTextNode($string));
// add the part from the list as new text node
$node->parentNode->insertBefore(
$dom->createTextNode($part),
$node
);
}
// remove the old text node
$node->parentNode->removeChild($node);
}
echo $dom->saveXml($dom->documentElement);
Output:
<p>
This is a test node with <xref>Figure 1</xref>.
</p>
Use DOMDocument to replace text with href link
As I can see a '
is misplaced,
<a href='http://test.de>test</a>'
This is not something you should want,
replace it with this,
<a href='http://test.de'>test</a>
As I've seen this Link, you may use preg_replace()
instead of preg_replace_dom()
at your last line of code.
Hope this helps.
DOMElement replace HTML value
Have you tried the DOMDocument::saveXML
function? (http://php.net/manual/en/domdocument.savexml.php)
It has a second argument $node
with which you can specify which node to print the HTML/XML of.
So, for example:
<?php
$doc = new DOMDocument('1.0');
// we want a nice output
$doc->formatOutput = true;
$root = $doc->createElement('body');
$root = $doc->appendChild($root);
$title = $doc->createElement('h1', 'Home');
$root->appendChild($title);
$text = $doc->createTextNode('test{{test}}');
$text = $root->appendChild($text);
echo $doc->saveXML($root);
?>
This will give you:
<body>
<h1>Home</h1>
test{{test}}
</body>
If you do not want the <body>
tag, you could cycle through all of its childnodes:
<?php
foreach($root->childNodes as $child){
echo $doc->saveXML($child);
}
?>
This will give you:
<h1>Home</h1>test{{test}}
Edit: you can then of course replace {{test}}
by the regex that you are already using:
<?php
$xml = '';
foreach($root->childNodes as $child){
$xml .= preg_replace(
'/(?<replaceable>{{([a-z0-9_]+)}})/mi', '',
$doc->saveXML($child)
);
}
?>
This will give you:
<h1>Home</h1>test
Note: I haven't tested the code, but this should give you the general idea.
How to replace a node with a string using DOMDocument
You have not shown any code so far so it is not really clear into which problem you run. I can only assume that it is because if you iterate over the list of links changing it, the iteration will get invalid. So only the first element is being replaced.
Using a for
loop can help here only getting the first a element per each iteration. It would also allow to initialize and increase the count variable for the numbers you need in the replacement.
The replacement itself can be easily done with replaceChild
. The loop example:
for($c = 1; $a = $doc->getElementsByTagName('a')->item(0); $c++) {
$a->parentNode->replaceChild(
$doc->createTextNode(sprintf("@@%d@@", $c)),
$a
);
}
The call to $doc->getElementsByTagName('a')->item(0)
will return NULL
if no such element exists (any longer). That is the exit condition of the loop.
Full example:
$html = '<html><body>
Lorum ipsum <a href="http://google.com">click here</a> dolores lorem.
Lorum ipsum <a href="http://stackoverflow.com">click here too</a> dolores lorem.
</body></html>';
$doc = new DOMDocument();
$doc->loadHtml($html);
for($c = 1; $a = $doc->getElementsByTagName('a')->item(0); $c++) {
$a->parentNode->replaceChild(
$doc->createTextNode(sprintf("@@%d@@", $c)),
$a
);
}
echo $doc->saveHTML();
Output:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
Lorum ipsum @@1@@ dolores lorem.
Lorum ipsum @@2@@ dolores lorem.
</body></html>
I hope this is helpful.
Replacing innertext of XML node using PHP DOMDocument
So, since you have created DOMDocument
you can use DOMXpath. Or keep using getElementsByTagName()
You could do this (but only in that context):
$descriptions = $root->getElementsByTagName('description');
foreach($descriptions as $nodeDesciption)
{
$nodeDesciption->nodeValue ='Your custom value';
}
Related Topics
Most Efficient Way to Get Next Letter in the Alphabet Using PHP
Call to Undefined Function Curl_Init() Even It Is Enabled in PHP7
Checking If a String Contains an Integer
How to Serve an Image with Laravel
How to Get the Home Directory from a PHP Cli Script
Using Print_R and Var_Dump with Circular Reference
How to Get All Checkbox Variables Even If Not Checked from HTML to PHP
Doctrine2 Association Mapping with Conditions
How to Determine Whether It's a Mobile Device with PHP
Compile Error: "G++: Error Trying to Exec 'Cc1Plus': Execvp: No Such File or Directory"
How to Validate Phone Number Using PHP
How to Check If a Longitude/Latitude Point Is Within a Range of Coordinates
Fatal Error: Call to Undefined Function Pg_Connect()
When to Wrap Curly Braces Around a Variable