Remove namespace from XML using PHP
If you're using XPath then it's a limitation with XPath and not PHP look at this explanation on xpath and default namespaces for more info.
More specifically its the xmlns=""
attribute in the root node which is causing the problem. This means that you'll need to register the namespace then use a QName thereafter to refer to elements.
$feed = simplexml_load_file('http://www.sitepoint.com/recent.rdf');
$feed->registerXPathNamespace("a", "http://www.domain.com/schema/data");
$result = $feed->xpath("a:Data/a:Something/...");
Important: The URI used in the registerXPathNamespace
call must be identical to the one that is used in the actual XML file. How to remove namespace with PHP SimpleXMLElement?
You can use 3rd parameter with blank value for addChild method. $xml->addChild('ItPrice', '1337', '');
$xml = new SimpleXMLElement('<yq1:ZwsCreteMaterialFrRef xmlns:yq1="urn:test-com:document:test:soap:functions:mc-style"></yq1:ZwsCreteMaterialFrRef>');
$namespaces = $xml->getDocNamespaces();
$xml->addChild('ItPrice', '1337', '');
echo $xml->asXml();
Remove Namespace from child Element XML PHP
SimpleXMLElement::addChild
needs the namespace (if not the default one) in its third parameter.
If the namespace is not yet registered, it will be added. This is what you see in your result.
However you want to add a child element in a specific, existing namespace, namely http://base.google.com/ns/1.0
(it looks like an URL, however in terms of XML it is just a string).
Example:
$namespace = 'http://base.google.com/ns/1.0';
$root->channel->item->addChild('id', '456', $namespace);
# adds child <g:id>456</g:id>
This is what you want: Add the id
element in the http://base.google.com/ns/1.0
namespace.Here the namespace is abbreviated with g
, the so called prefix (g:...
). You can imagine the element name is {http://base.google.com/ns/1.0}id
("Clark notation").
See the first (root/document) element there you can see which prefix stands for which namespace:
<rss xmlns:g="http://base.google.com/ns/1.0"
xmlns:c="http://base.google.com/cns/1.0" version="2.0">
This is why by only using id
for the element name when adding and telling the correct namespace, it is inserted with the g
prefix.However when you explicitly specify the prefix in the name adding the child element and providing a (new) namespace, the namespace for that elements' prefix will be with the added child because you told SimpleXML to do so (in your case by chance/error not intend, but that is just for explanation what happened).
<g:id xmlns:g="id">123</g:id>
- Element name is
id
; with prefix:g:id
; with namespace:{id}id
- Namespace is
id
- Prefix in this (and all its child elements) for it is
g
http://base.google.com/ns/1.0
.To find it, look up to the element that has the xmlns:<prefix>
attribute, then see the value:
<rss xmlns:g="http://base.google.com/ns/1.0" ...>
^ \___________________________/
| namespace
prefix g is ---/
When you call addChild()
with that namespace, an existing prefix (here: g
) will be automatically chosen by SimpleXML.But if that child element is the first element with that (new to the document) namespace, it will be added as in your case with the xmlns
attribute (all attributes starting with xml
(case insensitive) are reserved attribute names in XML, same for element names):
<g:price xmlns:g="price">0.00</g:price>
Prefix "g" is namespace "price" for that "price" element (and all its children if there would be any until another child element redefines the namespace of the prefix).If you're now explicitly looking (in code) for what namespace which prefix is, you can obtain an associative array by calling SimpleXMLElement::getNamespaces
:
$namespace = $root->getNamespaces(true)['g'];
However using the real namespace name is much better as the prefix can by anything and may change while the namespace name remains stable. Also its less code to write:$namespace = 'http://base.google.com/ns/1.0';
$root->channel->item->addChild('id', '456', $namespace);
How to remove all namespaces from XML in PHP (tags and attributes)
To rewrite a complete XML document like renaming element or attribute names as well as changing namespace related data like xmlns
attributes, you can use the expat based xml parser extension:
- PHP XML Parser
You then can change these values on the fly and output the (potentially changed) data.
Done this way you don't need to care about regular expressions any longer (which is non-trivial for proper XML parsing).
You can find some boilerplate code to get this started in a previous answer of mine.
PHP/SOAP - Remove all namespaces BUT first
Consider XSLT, the special-purpose language designed to transform XML files and manipulating namespaces are among its regular uses. PHP can run XSLT 1.0 scripts using its php-xsl class. With this approach no array
builds, foreach
loops, if
logic, or recursive function
are needed.
XSLT (save as .xsl file, a special .xml file)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- IDENTITY TRANSFROM: COPY DOC AS IS -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- REMOVE NAMESPACE PREFIXES -->
<xsl:template match="*[local-name()!='Contract']">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Input XML (assuming below replicates OP's return)<?xml version="1.0" encoding="UTF-8"?>
<sof:Contract xmlns:s="http://www.fines.pl/simple" xmlns:sof="http://www.fines.pl/sof" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.fines.pl/sof model.xsd ">
<sof:product>
<sof:prefix>MOP</sof:prefix>
</sof:product>
<sof:participants>
<sof:customers>
<sof:main_borrower>
<sof:personal_data>
<sof:pesel></sof:pesel>
<sof:firstname></sof:firstname>
<sof:lastname></sof:lastname>
<sof:firstname_father></sof:firstname_father>
<sof:firstname_mother></sof:firstname_mother>
<sof:secondname />
<sof:sex>female</sof:sex>
</sof:personal_data>
<sof:contact_data>
<sof:addresses>
<sof:address>
<sof:type>registered</sof:type>
<sof:street_name></sof:street_name>
<sof:block_number></sof:block_number>
<sof:flat_number></sof:flat_number>
<sof:postal_code></sof:postal_code>
<sof:city></sof:city>
</sof:address>
</sof:addresses>
<sof:phones_mobile>
<sof:phone_mobile>
<sof:type>personal</sof:type>
<sof:number>602200300</sof:number>
</sof:phone_mobile>
</sof:phones_mobile>
</sof:contact_data>
<sof:incomes>
<sof:income>
<sof:type>employment</sof:type>
<sof:main_income>true</sof:main_income>
<sof:fixed_term_contract>false</sof:fixed_term_contract>
<sof:paychecks>
<sof:paycheck>
<sof:amount_net>
<sof:amount>1444.00</sof:amount>
<sof:currency>PLN</sof:currency>
</sof:amount_net>
<sof:type>base</sof:type>
</sof:paycheck>
</sof:paychecks>
</sof:income>
</sof:incomes>
<sof:household_pointer>/households.0</sof:household_pointer>
</sof:main_borrower>
</sof:customers>
</sof:participants>
</sof:Contract>
PHP// LOAD XML AND XSLT
$doc = new DOMDocument();
$doc->load('Input.xml');
$xsl = new DOMDocument;
$xsl->load('XSLTScript.xsl');
// CONFIGURE TRANSFORMER
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);
// RUN TRANSFORMATION
$newXML = $proc->transformToXML($doc);
// ECHO TO CONSOLE
echo $newXML;
// SAVE OUTPUT TO FILE
file_put_contents('Output.xml', $newXML);
Output XML (prefixes removed for all but the root)<?xml version="1.0" encoding="utf-8"?>
<sof:Contract xsi:schemaLocation="http://www.fines.pl/sof model.xsd " xmlns:sof="http://www.fines.pl/sof" xmlns:s="http://www.fines.pl/simple" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<product>
<prefix>MOP</prefix>
</product>
<participants>
<customers>
<main_borrower>
<personal_data>
<pesel />
<firstname />
<lastname />
<firstname_father />
<firstname_mother />
<secondname />
<sex>female</sex>
</personal_data>
<contact_data>
<addresses>
<address>
<type>registered</type>
<street_name />
<block_number />
<flat_number />
<postal_code />
<city />
</address>
</addresses>
<phones_mobile>
<phone_mobile>
<type>personal</type>
<number>602200300</number>
</phone_mobile>
</phones_mobile>
</contact_data>
<incomes>
<income>
<type>employment</type>
<main_income>true</main_income>
<fixed_term_contract>false</fixed_term_contract>
<paychecks>
<paycheck>
<amount_net>
<amount>1444.00</amount>
<currency>PLN</currency>
</amount_net>
<type>base</type>
</paycheck>
</paychecks>
</income>
</incomes>
<household_pointer>/households.0</household_pointer>
</main_borrower>
</customers>
</participants>
</sof:Contract>
How to remove namespace from HTML content in XML file
I must have glossed over this in the documentation.
It took a little while to find, but the following seems to work well:
$content = $xpath->query('a:content/h:*', $context);
foreach ($content as $piece)
{
$piece->removeAttributeNS('http://www.w3.org/1999/xhtml', 'h');
$html_content .= $dom->saveXML($piece);
}
Hope this helps someone else trying to solve the same issue. remove Name-Space from xml file and save as new XML
first create on simple php file to load xml From the URL:-
<?php
$dom = new DOMDocument();
$dom->load('http://services.gisgraphy.com/geoloc/search?lat=22.298569900000000000&lng=70.794301799999970000&radius=7000', true);
$dom->save('filename.xml');
?>
then create one XSLT file:-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="xml" version="1.0" encoding="UTF-8" />
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
and create one php file to load xml file and implement our xslt file:-<?php
$sourcedoc->load('filename.xml');
$stylesheet = new DOMDocument();
$stylesheet->load('new4convert.xsl');
// create a new XSLT processor and load the stylesheet
$xsltprocessor = new XSLTProcessor();
$xsltprocessor->importStylesheet($stylesheet);
// save the new xml file
file_put_contents('filename.xml', $xsltprocessor->transformToXML($sourcedoc));
?>
final total code if you want to all in one PHP file:-<?php
$dom = new DOMDocument();
$dom->load('http://services.gisgraphy.com/geoloc/search?lat=22.298569900000000000&lng=70.794301799999970000&radius=7000', true);
$dom->save('filename.xml');
$sourcedoc = new DOMDocument();
$sourcedoc->load('filename.xml');
$stylesheet = new DOMDocument();
$stylesheet->load('new4convert.xsl');
// create a new XSLT processor and load the stylesheet
$xsltprocessor = new XSLTProcessor();
$xsltprocessor->importStylesheet($stylesheet);
// save the new xml file
file_put_contents('filename.xml', $xsltprocessor->transformToXML($sourcedoc));
?>
Related Topics
Zend Framework - Multiplate Navigation Blocks
PHP MySQL Pagination with Random Ordering
Rounding Up to the Second Decimal Place
Why Doesn't PHP Permit Private Const
How to Connect an Oracle Database from PHP
PHP Readfile() Causing Corrupt File Downloads
Adding an Admin Page on Opencart Version 2
Pdo_Sqlite Driver Not Present.. What to Do
Unchecked Checkbox Returning Null Value
Phpstorm: How to Add Method Stubs from a Pecl Library That PHPstorm Doesn't Currently Support
PHP Curl: Curlopt_Connecttimeout VS Curlopt_Timeout