but what I want to get is a child without a namespace declaration from parent xmlns = "default_ns".
This cannot be achieved only by evaluating the XPath expression.
In XML, any element inherits all its parent namespace nodes , unless it redefines a specific namespace.
This means that some_prefix:a
inherits the default namespace "default_ns"
from its parent ( subelement
), which inherits the same default namespace node from the top root
element.
XPath is a query language for XML documents. Thus, it only helps to select nodes, but evaluating an XPath expression never destroys, adds, or modifies nodes, including namespace nodes .
Because of this, the default namespace node belonging to some_prefix:a
cannot be destroyed as a result of evaluating your XPath expression, so this node namespace is displayed when some_prefix:a
serialized into text.
Solution . Use your favorite PL that hosts XPath to remove the unwanted node namespace.
For example, if the hosting language is XSLT :
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:d="default_ns"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="/"> <xsl:apply-templates mode="delNS" select="/*/d:subelement/*[1]"/> </xsl:template> <xsl:template match="*" mode="delNS"> <xsl:element name="{name()}" namespace="{namespace-uri()}"> <xsl:copy-of select="namespace::*[name()]"/> <xsl:copy-of select="@*"/> <xsl:apply-templates mode="delNS" select="node()"/> </xsl:element> </xsl:template> </xsl:stylesheet>
when this conversion is applied to the provided XML document :
<root xmlns="default_ns"> <subelement> <some_prefix:a xmlns:some_prefix="some_namespace"> <some_prefix:b/> </some_prefix:a> </subelement> </root>
required, the correct result is obtained :
<some_prefix:a xmlns:some_prefix="some_namespace"> <some_prefix:b/> </some_prefix:a>