I've got a long string which I want to split accross multiple lines so it's easier to read. but I'm not sure what the syntax is
$xml = array('sXML' =>"<queryxml><entity>Ticket</entity><query><field>Status<expression op=\"$condition1\">$complete</expression></field><condition operator=\"AND\"><field>AccountID<expression op=\"equals\">$userid</expression></field></condition><condition operator=\"AND\"><condition><field>QueueID<expression op=\"NotEqual\">$routine</expression></field></condition><condition operator=\"OR\"><field>QueueID<expression op=\"NotEqual\">$recurring</expression></field></condition><condition operator=\"OR\"><field>QueueID<expression op=\"NotEqual\">$clientmanagement</expression></field></condition></condition></query></queryxml>");
Can someone help me out please?
just split it into multiple strings and concatenate them, like this:
$xml = array('sXML' => "lorem" .
"ipsum" .
"dolor");
or use heredoc:
$sXML = <<<XML
your text
goes here
XML;
$xml = array('sXML' => $sXML);
If it doesn't matter if linebreaks are added, you can simply write:
<?php
$xml = array('sXML' => "<abc>
<def>Asdfg</def>
</abc>";
?>
Related
"contentDetails" has following data in it:
<p>This is data sample. </p><p>Second part of the paragraph. </p>
str_replace is not working here. Please take a look.
here is how my xml strucuture in php looks like:
$xml = <?xml version="1.0" encoding="UTF-8">;
$xml = '<root>';
$xml = '<myData>';
$xml .= <content> . str_replace(" ", "", htmlentities($_POST[contentDetails])) . </content>
$xml = '</myData>';
$xml = '</root>';
I'm assuming your contentDetails actually contains:
<p>This is data sample. </p><p>Second part of the paragraph. </p>
($nbsp; replaced with )
Your problem is that when you call htmlentities on contentDetails it converts into , so your str_replace won't find any matches. To solve the problem, call str_replace before htmlentities:
$xml .= '<content>' . htmlentities(str_replace(" ", "", $_POST['contentDetails'])) . '</content>';
Note that associative array keys should be enclosed in quotes; this will cause a warning now but in future PHP versions will be an error.
The htmlentities() function converts to --- so try this...
str_replace(" ", "", htmlentities($_POST[contentDetails]))
I'd like to replace the value in this tag using PHP's str_replace function:
<address2>Replace this value</address2>
What is the best approach to do this?
Try this :
$nodeAdresseValue = str_replace("%value%", "your value", "<address2>%value%</address2>");
Do not use string functions on XML, use DOMDocument instead, it'll help you parse XML more easily, here is an example code DEMO:
<?php
$string = "<address2>Replace this value</address2>";
$domDocument = new DOMDocument();
$domDocument->loadXML($string);
$address2Elements = $domDocument->getElementsByTagName('address2');
foreach ($address2Elements as $address2) {
$address2->nodeValue = "Value Replaced";
}
var_dump($domDocument->saveXML());
Output:
string(58) "<?xml version="1.0"?>
<address2>Value Replaced</address2>
"
$search = "/[^<address2>](.*)[^<\/address2>]/";
$replace = "replace with me";
$string = "<address2>Replace this value </address2>";
echo preg_replace($search,$replace,$string);
this will work irrespective of the text, it will work even if you dont know the value inside tags
I have a String which looks something like this:
$html_string = "<p>Some content</p><p>separated by</p><p>paragraphs</p>"
I'd like to do some parsing on the content inside the tags, so I think that creating an array from this would be easiest. Currently I'm using a series of explode and implode to achieve what I want:
$stripped = explode('<p>', $html_string);
$joined = implode(' ', $stripped);
$parsed = explode('</p>', $joined);
which in effect gives:
array('Some content', 'separated by', 'paragraphs');
Is there a better, more robust way to create an array from HTML tags? Looking at the docs, I didn't see any mention of parsing via a regular expression.
Thanks for your help!
If its only that simple with no/not much other tags inside the content you can simply use regex for that:
$string = '<p>Some content</p><p>separated by</p><p>paragraphs</p>';
preg_match_all('/<p>([^<]*?)<\/p>/mi', $string, $matches);
var_dump($matches[1]);
which creates this output:
array(3) {
[0]=>
string(12) "Some content"
[1]=>
string(12) "separated by"
[2]=>
string(10) "paragraphs"
}
Keep in mind that this is not the most effective way nor is it the fastest, but its shorter then using DOMDocument or anything like that.
If you need to do some html parsing in php, there is a nice library for that, called php html parser.
https://github.com/paquettg/php-html-parser
which can give you a jquery like api, to parse html.
an example:
// Assuming you installed from Composer:
require "vendor/autoload.php";
use PHPHtmlParser\Dom;
$dom = new Dom;
$dom->load('<p>Some content</p><p>separated by</p><p>paragraphs</p>');
$pTags = $dom->find('p');
foreach ($pTags as $tag)
{
// do something with the html
$content = $tag->innerHtml;
}
Here is the DOMDocument solution (native PHP), which will also work when your p tags have attributes, or contain other tags like <br>, or have lots of white-space in between them (which is irrelevant in HTML rendering), or contain HTML entities like or <, etc, etc:
$html_string = "<p>Some content</p><p>separated by</p><p>paragraphs</p>";
$doc = new DOMDocument();
$doc->loadHTML($html_string);
foreach($doc->getElementsByTagName('p') as $p ) {
$paras[] = $p->textContent;
}
// Output array:
print_r($paras);
If you really want to stick with regular expressions, then at least allow tag attributes and HTML entities, translating the latter to their corresponding characters:
$html_string = "<p>Some content & text</p><p>separated by</p><p style='background:yellow'>paragraphs</p>";
preg_match_all('/<p(?:\s.*?)?>\s*(.*?)\s*<\/p\s*>/si', $html_string, $matches);
$paras = $matches[1];
array_walk($paras, 'html_entity_decode');
print_r($paras);
My code is
$words = array();
$links = array();
$result = mysql_query("SELECT `keyword`, `link` FROM `articles` where `link`!='".$act."' ")
or die(mysql_error());
$i = 0;
while($row = mysql_fetch_array( $result ))
{
if (!empty($row['keyword']))
{
$words[$i] = '/(?<!(src="|alt="))'.$row['keyword'].'/i';
$links[$i] = ''.$row['keyword'].'';
$i++;
}
}
$text = preg_replace($words, $links, $text);
I want to replace Hello with Guys except img src and alt.
From
Say Hello my dear <img src="say-hello-my-dear.jpg" alt="say hello my dear" />
I want
Say Guys my dear <img src="say-hello-my-dear.jpg" alt="say hello my dear" />
The current code, replaces only when my keyword has only 1 word.
EDIT: the previsouly suggested correction was not relevant.
Still:
I would suggest you not to use any regex but only str_replace in your case if you have a performance constraint.
You must change your MySQL functions that are legacy: http://php.net/manual/en/function.mysql-fetch-array.php
EDIT: I can't believe it took me that long to understand that you're trying to parse big chunks of HTML with regular expressions.
Read the answer to this question:
RegEx match open tags except XHTML self-contained tags
Edit: I updated the code to work better.
I'm unsure exactly what the issue is but looking at your code I wouldn't be surprised that the negative look behind regex isn't matching multiple word strings where the "keyword" is not the first word after the src or alt. It might possible to beef up the regex, but IMHO a complicated regex might be a little too brittle for your html parsing needs. I'd recommend doing some basic html parsing yourself and doing a simple string replace in the right places.
Here's some basic code. There is certainly a much better solution than this, but I'm not going to spend too much time on this. Probably, rather than inserting html in a text node, you should create a new html a element with the right attributes. Then you wouldn't have to decode it. But this would be my basic approach.
$text = "Lorem ipsum <img src=\"lorem ipsum\" alt=\"dolor sit amet\" /> dolor sit amet";
$result = array(
array('keyword' => 'lorem', 'link' => 'http://www.google.com'),
array('keyword' => 'ipsum', 'link' => 'http://www.bing.com'),
array('keyword' => 'dolor sit', 'link' => 'http://www.yahoo.com'),
);
$doc = new DOMDocument();
$doc->loadHTML($text);
$xpath = new DOMXPath($doc);
foreach($result as $row) {
if (!empty($row['keyword'])) {
$search = $row['keyword'];
$replace = ''.$row['keyword'].'';
$text_nodes = $xpath->evaluate('//text()');
foreach($text_nodes as $text_node) {
$text_node->nodeValue = str_ireplace($search, $replace, $text_node->nodeValue);
}
}
}
echo html_entity_decode($doc->saveHTML());
The $result data structure is meant to be similar to result of your mysql_fetch_array(). I'm only getting the children of the root for the created html DOMDocument. If the $text is more complicated, it should be pretty easy to traverse more thoroughly through the document. I hope this helps you.
I have to parse externally provided XML that has attributes with line breaks in them. Using SimpleXML, the line breaks seem to be lost. According to another stackoverflow question, line breaks should be valid (even though far less than ideal!) for XML.
Why are they lost? [edit] And how can I preserve them? [/edit]
Here is a demo file script (note that when the line breaks are not in an attribute they are preserved).
PHP File with embedded XML
$xml = <<<XML
<?xml version="1.0" encoding="utf-8"?>
<Rows>
<data Title='Data Title' Remarks='First line of the row.
Followed by the second line.
Even a third!' />
<data Title='Full Title' Remarks='None really'>First line of the row.
Followed by the second line.
Even a third!</data>
</Rows>
XML;
$xml = new SimpleXMLElement( $xml );
print '<pre>'; print_r($xml); print '</pre>';
Output from print_r
SimpleXMLElement Object
(
[data] => Array
(
[0] => SimpleXMLElement Object
(
[#attributes] => Array
(
[Title] => Data Title
[Remarks] => First line of the row. Followed by the second line. Even a third!
)
)
[1] => First line of the row.
Followed by the second line.
Even a third!
)
)
Using SimpleXML, the line breaks seem to be lost.
Yes, that is expected... in fact it is required of any conformant XML parser that newlines in attribute values represent simple spaces. See attribute value normalisation in the XML spec.
If there was supposed to be a real newline character in the attribute value, the XML should have included a
character reference instead of a raw newline.
The entity for a new line is
. I played with your code until I found something that did the trick. It's not very elegant, I warn you:
//First remove any indentations:
$xml = str_replace(" ","", $xml);
$xml = str_replace("\t","", $xml);
//Next replace unify all new-lines into unix LF:
$xml = str_replace("\r","\n", $xml);
$xml = str_replace("\n\n","\n", $xml);
//Next replace all new lines with the unicode:
$xml = str_replace("\n","
", $xml);
Finally, replace any new line entities between >< with a new line:
$xml = str_replace(">
<",">\n<", $xml);
The assumption, based on your example, is that any new lines that occur inside a node or attribute will have more text on the next line, not a < to open a new element.
This of course would fail if your next line had some text that was wrapped in a line-level element.
Assuming $xmlData is your XML string before it is sent to the parser, this should replace all newlines in attributes with the correct entity. I had the issue with XML coming from SQL Server.
$parts = explode("<", $xmlData); //split over <
array_shift($parts); //remove the blank array element
$newParts = array(); //create array for storing new parts
foreach($parts as $p)
{
list($attr,$other) = explode(">", $p, 2); //get attribute data into $attr
$attr = str_replace("\r\n", "
", $attr); //do the replacement
$newParts[] = $attr.">".$other; // put parts back together
}
$xmlData = "<".implode("<", $newParts); // put parts back together prefixing with <
Probably can be done more simply with a regex, but that's not a strong point for me.
Here is code to replace the new lines with the appropriate character reference in that particular XML fragment. Run this code prior to parsing.
$replaceFunction = function ($matches) {
return str_replace("\n", "
", $matches[0]);
};
$xml = preg_replace_callback(
"/<data Title='[^']+' Remarks='[^']+'/i",
$replaceFunction, $xml);
This is what worked for me:
First, get the xml as a string:
$xml = file_get_contents($urlXml);
Then do the replacement:
$xml = str_replace(".\xe2\x80\xa9<as:eol/>",".\n\n<as:eol/>",$xml);
The "." and "< as:eol/ >" were there because I needed to add breaks in that case. The new lines "\n" can be replaced with whatever you like.
After replacing, just load the xml-string as a SimpleXMLElement object:
$xmlo = new SimpleXMLElement( $xml );
Et VoilĂ
Well, this question is old but like me, someone might come to this page eventually.
I had slightly different approach and I think the most elegant out of these mentioned.
Inside the xml, you put some unique word which you will use for new line.
Change xml to
<data Title='Data Title' Remarks='First line of the row. \n
Followed by the second line. \n
Even a third!' />
And then when you get path to desired node in SimpleXML in string output write something like this:
$findme = '\n';
$pos = strpos($output, $findme);
if($pos!=0)
{
$output = str_replace("\n","<br/>",$output);
It doesn't have to be '\n, it can be any unique char.