I am finding that, for my purposes, XML namespaces are simply causing much headache and are pletely unnecessary. (For example, how they plicate xpath.)
Is there a simple way to remove namespaces entirely from an XML document?
(There is a related question, but it deals with removing namespace prefixes on tags, rather than namespace declarations from the document root: "Easy way to drop XML namespaces with javascript".)
Edit: Samples and more detail below:
XML:
<?xml version="1.0" ?>
<main xmlns="example">
<primary>
<enabled>true</enabled>
</primary>
<secondary>
<enabled>false</enabled>
</secondary>
</main>
JavaScript:
function useHttpResponse()
{
if (http.readyState == 4)
{
if(http.status == 200)
{
var xml = http.responseXML;
var evalue = getXMLValueByPath('/main/secondary/enabled', xml);
alert(evalue);
}
}
}
function getXMLValueByPath(nodepath, xml)
{
var result = xml.evaluate(nodepath, xml, null, XPathResult.STRING_TYPE, null).stringValue;
return result;
}
The sample XML is just like the actual one I am working with, albeit much shorter. Notice that there are no prefixes on the tags for the namespace. I assume this is the null or default namespace.
The JavaScript is a snippet from my ajax functions. If I remove the xmlns="example"
portion from the main
tag, I am able to successfully get the value. As long as any namespace is present, the value bees undefined.
Edit 2:
It may be worth mentioning that none of the declared namespaces are actually used in the XML tags (like the sample above). In the actual XML file I am working with, three namespaces are declared, but no tags are prefixed with a namespace reference. Thus, perhaps the question should be re-titled, "How to remove unused XML namespaces using Javascript?" I do not see the reason to retain a namespace if it is 1) never used and 2) plicating an otherwise simple path to a node using xpath.
I am finding that, for my purposes, XML namespaces are simply causing much headache and are pletely unnecessary. (For example, how they plicate xpath.)
Is there a simple way to remove namespaces entirely from an XML document?
(There is a related question, but it deals with removing namespace prefixes on tags, rather than namespace declarations from the document root: "Easy way to drop XML namespaces with javascript".)
Edit: Samples and more detail below:
XML:
<?xml version="1.0" ?>
<main xmlns="example.">
<primary>
<enabled>true</enabled>
</primary>
<secondary>
<enabled>false</enabled>
</secondary>
</main>
JavaScript:
function useHttpResponse()
{
if (http.readyState == 4)
{
if(http.status == 200)
{
var xml = http.responseXML;
var evalue = getXMLValueByPath('/main/secondary/enabled', xml);
alert(evalue);
}
}
}
function getXMLValueByPath(nodepath, xml)
{
var result = xml.evaluate(nodepath, xml, null, XPathResult.STRING_TYPE, null).stringValue;
return result;
}
The sample XML is just like the actual one I am working with, albeit much shorter. Notice that there are no prefixes on the tags for the namespace. I assume this is the null or default namespace.
The JavaScript is a snippet from my ajax functions. If I remove the xmlns="example."
portion from the main
tag, I am able to successfully get the value. As long as any namespace is present, the value bees undefined.
Edit 2:
It may be worth mentioning that none of the declared namespaces are actually used in the XML tags (like the sample above). In the actual XML file I am working with, three namespaces are declared, but no tags are prefixed with a namespace reference. Thus, perhaps the question should be re-titled, "How to remove unused XML namespaces using Javascript?" I do not see the reason to retain a namespace if it is 1) never used and 2) plicating an otherwise simple path to a node using xpath.
Share Improve this question edited May 23, 2017 at 12:28 CommunityBot 11 silver badge asked Dec 22, 2010 at 0:03 JYeltonJYelton 36.5k27 gold badges137 silver badges194 bronze badges 20- Namespaces are of no value, right up until they are needed. – John Saunders Commented Dec 22, 2010 at 0:53
- The irony here is that namespaces were apparently developed to allow duplicate tags and avoid confusion between them. I have duplicate tags with differing parent tags, and am attempting to use xpath to select them. If I remove the namespace declaration manually, it's quite simple to select the elements. With the namespace declaration intact, it fails entirely. – JYelton Commented Dec 22, 2010 at 1:02
- 2 Why not ask for help with using namespaces instead of giving up? – John Saunders Commented Dec 22, 2010 at 2:42
- Namespaces shouldn't plicate xpath particularly, you just namespace the parts inside the xpath as you go. Maybe it would be better to figure out why your xpath isn't working, rather than stripping out structural data? – Erica Commented Dec 22, 2010 at 3:16
- "but it deals with removing namespaces on tags, rather than from the entire document" - can you explain the difference? Do you mean you want to remove namespace declarations? Namespace prefixes? What does it mean to remove namespaces from an entire document other than removing them from tags? – LarsH Commented Dec 22, 2010 at 4:19
3 Answers
Reset to default 6This should remove any namespace declaration you find:
var xml = http.responseXML.replace(/<([a-zA-Z0-9 ]+)(?:xml)ns=\".*\"(.*)>/g, "<$1$2>");
Inorder to replace all the xmlns attributes from an XML javascript string
you can try the following regex
xmlns=\"(.*?)\"
NB: This regex can be used to replace any attributes
var str = `<?xml version="1.0" ?>
<main xmlns="example.">
<primary>
<enabled>true</enabled>
</primary>
<secondary>
<enabled>false</enabled>
</secondary>
</main>`;
str = str.replace(/xmlns=\"(.*?)\"/g, '');
console.log(str)
Approach without using regex (This removes attributes also)
let xml = '';//input
let doc = new DOMParser().parseFromString(xml,"text/xml");
var root=doc.firstElementChild;
var newdoc = new Document();
newdoc.appendChild(removeNameSpace(root));
function removeNameSpace (root){
let parentElement = document.createElement(root.localName);
let nodeChildren = root.childNodes;
for (let i = 0; i <nodeChildren.length; i++) {
let node = nodeChildren[i];
if(node.nodeType == 1){
let child
if(node.childElementCount!=0)
child = removeNameSpace(node);
else{
child = document.createElement(node.localName);
let textNode = document.createTextNode(node.innerHTML);
child.append(textNode);
}
parentElement.append(child);
}
}
return parentElement;
}