0

How to remove all nodes like xml:space="preserve" from XML, to get clean result

old XML

<table>
<actor xml:space="preserve"> </actor>
</table>

I want result be like this

<table>
<actor> </actor>
</table>

EDIT

this the php code

function produce_XML_object_tree($raw_XML) {
    libxml_use_internal_errors(true);
    try {
        $xmlTree = new SimpleXMLElement($raw_XML);
    } catch (Exception $e) {
        // Something went wrong.
        $error_message = 'SimpleXMLElement threw an exception.';
        foreach(libxml_get_errors() as $error_line) {
            $error_message .= "\t" . $error_line->message;
        }
        trigger_error($error_message);
        return false;
    }
    return $xmlTree;
}
$xml_feed_url = "www.xmlpage.com/web.xml";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $xml_feed_url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$xml = curl_exec($ch);
curl_close($ch);

$cont = produce_XML_object_tree($xml);

echo json_encode($cont);
haz azezan
  • 27
  • 1
  • 10

3 Answers3

1

Use an xpath expression to locate the attributes and remove them.


Example:

//$xml = your xml string

$dom = new DOMDocument();
$dom->loadXML($xml);
$xpath = new DOMXPath($dom);

foreach ($xpath->query('//@xml:space') as $attr) {
    $attr->ownerElement->removeAttributeNode($attr);
}

echo $dom->saveXML();

Output:

<?xml version="1.0"?>
<table>
<actor> </actor>
</table>

This will remove any xml:space attributes. If you want to target only those xml:space attributes that have a value of "preserve", change the query to //@xml:space[.="preserve"].

user3942918
  • 25,539
  • 11
  • 55
  • 67
0

$string = str_ireplace('xml:space="preserve"','',$string);

function produce_XML_object_tree($raw_XML) {
    libxml_use_internal_errors(true);
    try {
        $xmlTree = new SimpleXMLElement($raw_XML);
    } catch (Exception $e) {
        // Something went wrong.
        $error_message = 'SimpleXMLElement threw an exception.';
        foreach(libxml_get_errors() as $error_line) {
            $error_message .= "\t" . $error_line->message;
        }
        trigger_error($error_message);
        return false;
    }
    return str_ireplace('xml:space="preserve"','',$xmlTree;);
}
$xml_feed_url = "www.xmlpage.com/web.xml";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $xml_feed_url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$xml = curl_exec($ch);
curl_close($ch);

$cont = produce_XML_object_tree($xml);

echo json_encode($cont);
valiD
  • 351
  • 1
  • 16
  • @valiD doesn't work return like this "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n" – haz azezan Mar 14 '15 at 22:03
0

As long as you're concerned to remove all attribute-nodes that are with a namespace prefix, you can do so by selecting them via xpath and remove them from the XML document.

The xpath query for all attributes with a prefix can be obtained by comparing the name (that is prefix and local-name) with the local-name (that is the local-name only). If it differs you've got a match:

//@*[name(.) != local-name(.)]

Querying specific nodes with SimpleXML and XPath to delete them has been outlined earlier as an answer to the question Remove a child with a specific attribute, in SimpleXML for PHP (Nov 2008) and is pretty straight-forward by using the SimpleXML-Self-Reference:

$xml = simplexml_load_string($buffer);
foreach ($xml->xpath('//@*[name(.) != local-name(.)]') as $attr) {
    unset($attr[0]);
}

The self-reference here is to remove the attribute $attr via $attr[0].

Full Example:

$buffer = <<<XML
<table>
<actor class="foo" xml:space="preserve"> </actor>
</table>
XML;

$xml = simplexml_load_string($buffer);
foreach ($xml->xpath('//@*[name(.) != local-name(.)]') as $attr) {
    unset($attr[0]);
}
echo $xml->asXML();

Example Output:

<?xml version="1.0"?>
<table>
<actor class="foo"> </actor>
</table>
Community
  • 1
  • 1
hakre
  • 193,403
  • 52
  • 435
  • 836