You can use the SimpleXMLElement::asXML() method to accomplish this:
$string = "<element><child>Hello World</child></element>";
$xml = new SimpleXMLElement($string);
// The entire XML tree as a string:
// "<element><child>Hello World</child></element>"
$xml->asXML();
// Just the child node as a string:
// "<child>Hello World</child>"
$xml->child->asXML();
Answer from user142162 on Stack OverflowYou can use the SimpleXMLElement::asXML() method to accomplish this:
$string = "<element><child>Hello World</child></element>";
$xml = new SimpleXMLElement($string);
// The entire XML tree as a string:
// "<element><child>Hello World</child></element>"
$xml->asXML();
// Just the child node as a string:
// "<child>Hello World</child>"
$xml->child->asXML();
You can use casting:
<?php
$string = "<element><child>Hello World</child></element>";
$xml = new SimpleXMLElement($string);
$text = (string)$xml->child;
$text will be 'Hello World'
The contents of the "string" element is an XML document itself - stored in an text node. You can consider it an envelope. So you have to load the outer XML document first and read the text content, then load it as an XML document again.
$outerXML = <<<'XML'
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://www.cebroker.com/CEBrokerWebService/"><licensees><licensee
valid="true" State="FL" licensee_profession="RN"
licensee_number="2676612" state_license_format="" first_name="HENRY"
last_name="GEITER" ErrorCode="" Message="" TimeStamp="2/19/2022
4:53:35 AM" /></licensees></string>
XML;
$envelope = new SimpleXMLElement($outerXML);
$licensees = new SimpleXMLElement((string)$envelope);
echo $licensees->asXML();
In DOM:
$envelope = new DOMDocument();
$envelope->loadXML($outerXML);
$document = new DOMDocument();
$document->loadXML($envelope->documentElement->textContent);
echo $document->saveXML();
Since the XML you want seem to be stored as htmlentities, your first simplexml_load_string() won't read it as XML. If you take that string and run that through simplexml_load_string() as well then you'll get it as XML:
$xml_string = simplexml_load_string($xmlresponse);
$licensees = simplexml_load_string($xml_string);
var_dump($licensees);
Output:
object(SimpleXMLElement)#2 (1) {
["licensee"]=>
object(SimpleXMLElement)#3 (1) {
["@attributes"]=>
array(10) {
["valid"]=>
string(4) "true"
["State"]=>
string(2) "FL"
["licensee_profession"]=>
string(2) "RN"
["licensee_number"]=>
string(7) "2676612"
["state_license_format"]=>
string(0) ""
["first_name"]=>
string(5) "HENRY"
["last_name"]=>
string(6) "GEITER"
["ErrorCode"]=>
string(0) ""
["Message"]=>
string(0) ""
["TimeStamp"]=>
string(21) "2/19/2022 4:53:35 AM"
}
}
}
Here's a demo: https://3v4l.org/da3Up
htmlspecialchars is what you need. It's a lot more selective, unlike htmlentities, over what it converts.
From htmlentities documentation:
This function is identical to htmlspecialchars() in all ways, except with htmlentities(), all characters which have HTML character entity equivalents are translated into these entities.
<?php
$a = "I love things & stuffë";
$b = htmlspecialchars(
c = htmlentities($a);
echo "$b\n$c\n";
Outputs:
I love things & stuffë
I love things & stuffë
http://www.php.net/manual/en/function.htmlspecialchars.php
If you create XML you likely have a DOMDocument at hand already. Even if not, you can easily create one. With a DOMDocument you can create text that is 100% well-formed for XML:
$text = "I'm using php v5.3. I would like to convert a string to valid xml. Xml apparently requires '&' characters to be encoded to & but all functions I can find which do this also convert characters like 'ë' to html entities xml doesn't accept (ë in this case). What function should I use?";
$doc = new DOMDocument();
echo $doc->saveXML($doc->createTextNode($text));
This gives you the following output (verbatim):
I'm using php v5.3. I would like to convert a string to valid xml. Xml apparently requires '&' characters to be encoded to &amp; but all functions I can find which do this also convert characters like 'ë' to html entities xml doesn't accept (&euml; in this case). What function should I use?
Try with simple XML, here's an example:
do.php:
<?php
$xml_str = file_get_contents('xmlfile.xml');
$xml = new SimpleXMLElement($xml_str);
$items = $xml->xpath('*/item');
foreach($items as $item) {
echo $item['title'], ': ', $item['description'], "\n";
}
xmlfile.xml:
<?xml version="1.0" encoding="UTF-8"?>
<xml>
<items>
<item title="Hello World" description="Hellowing the world.." />
<item title="Hello People" description="greeting people.." />
</items>
</xml>
For those situations where SimpleXML is not available, I use this function originally posted in a comment on php.net. It works great 99% of the time.
<?php
/**
* Convert XML to an Array
*
* @param string $XML
* @return array
*/
function XMLtoArray($XML)
{
$xml_parser = xml_parser_create();
xml_parse_into_struct($xml_parser, $XML, $vals);
xml_parser_free($xml_parser);
// wyznaczamy tablice z powtarzajacymi sie tagami na tym samym poziomie
$_tmp='';
foreach ($vals as $xml_elem) {
$x_tag=$xml_elem['tag'];
$x_level=$xml_elem['level'];
$x_type=$xml_elem['type'];
if ($x_level!=1 && $x_type == 'close') {
if (isset($multi_key[$x_tag][$x_level]))
$multi_key[$x_tag][$x_level]=1;
else
$multi_key[$x_tag][$x_level]=0;
}
if ($x_level!=1 && $x_type == 'complete') {
if ($_tmp==$x_tag)
$multi_key[$x_tag][$x_level]=1;
$_tmp=$x_tag;
}
}
// jedziemy po tablicy
foreach ($vals as $xml_elem) {
$x_tag=$xml_elem['tag'];
$x_level=$xml_elem['level'];
$x_type=$xml_elem['type'];
if ($x_type == 'open')
$level[$x_level] = $x_tag;
$start_level = 1;
$php_stmt = '$xml_array';
if ($x_type=='close' && $x_level!=1)
$multi_key[$x_tag][$x_level]++;
while ($start_level < $x_level) {
$php_stmt .= '[$level['.$start_level.']]';
if (isset($multi_key[$level[$start_level]][$start_level]) && $multi_key[$level[$start_level]][$start_level])
$php_stmt .= '['.($multi_key[$level[$start_level]][$start_level]-1).']';
$start_level++;
}
$add='';
if (isset($multi_key[$x_tag][$x_level]) && $multi_key[$x_tag][$x_level] && ($x_type=='open' || $x_type=='complete')) {
if (!isset($multi_key2[$x_tag][$x_level]))
$multi_key2[$x_tag][$x_level]=0;
else
$multi_key2[$x_tag][$x_level]++;
$add='['.$multi_key2[$x_tag][$x_level].']';
}
if (isset($xml_elem['value']) && trim($xml_elem['value'])!='' && !array_key_exists('attributes', $xml_elem)) {
if ($x_type == 'open')
$php_stmt_main=$php_stmt.'[$x_type]'.$add.'[\'content\'] = $xml_elem[\'value\'];';
else
$php_stmt_main=$php_stmt.'[$x_tag]'.$add.' = $xml_elem[\'value\'];';
eval($php_stmt_main);
}
if (array_key_exists('attributes', $xml_elem)) {
if (isset($xml_elem['value'])) {
$php_stmt_main=$php_stmt.'[$x_tag]'.$add.'[\'content\'] = $xml_elem[\'value\'];';
eval($php_stmt_main);
}
foreach ($xml_elem['attributes'] as $key=>$value) {
$php_stmt_att=$php_stmt.'[$x_tag]'.$add.'[$key] = $value;';
eval($php_stmt_att);
}
}
}
return $xml_array;
}
?>
imo, better way is to:
use heredoc with xml definition
$string = <<<XML <?xml version='1.0'?> ... // your xml here XML;return array, not
SimpleXMLElement Objectif he needs it, with$xml = (array)simplexml_load_string($string);
$str = '<ROOT>
<StartTime>7/9/2013
10:01:29
AM</StartTime>
<EndTime>7/9/2013
10:01:29
AM</EndTime>
<ROW_DATA>
<AMOUNT_ROOMS>2</AMOUNT_ROOMS>
<SUPP_MOVIE_NAME>tiz</SUPP_MOVIE_NAME>
<AMOUNT_NIS>3680</AMOUNT_NIS>
<PRICE_DOCKET_ID>1233</PRICE_DOCKET_ID>
</ROW_DATA>
<ROW_DATA>
<AMOUNT_ROOMS>1</AMOUNT_ROOMS>
<SUPP_MOVIE_NAME>mantiz</SUPP_MOVIE_NAME>
<AMOUNT_NIS>3690</AMOUNT_NIS>
<PRICE_DOCKET_ID>1234</PRICE_DOCKET_ID>
</ROW_DATA>
<StartTime>7/9/2013
10:01:29
AM</StartTime>
<EndTime>7/9/2013
10:01:30
AM</EndTime>
</ROOT>';
$xml = simplexml_load_string($str);
print_r($xml);
Output:
SimpleXMLElement Object
(
[StartTime] => Array
(
[0] => 7/9/2013
10:01:29
AM
[1] => 7/9/2013
10:01:29
AM
)
[EndTime] => Array
(
[0] => 7/9/2013
10:01:29
AM
[1] => 7/9/2013
10:01:30
AM
)
[ROW_DATA] => Array
(
[0] => SimpleXMLElement Object
(
[AMOUNT_ROOMS] => 2
[SUPP_MOVIE_NAME] => tiz
[AMOUNT_NIS] => 3680
[PRICE_DOCKET_ID] => 1233
)
[1] => SimpleXMLElement Object
(
[AMOUNT_ROOMS] => 1
[SUPP_MOVIE_NAME] => mantiz
[AMOUNT_NIS] => 3690
[PRICE_DOCKET_ID] => 1234
)
)
)