我有以下xml文件。
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns="http://example.com/ns">
<soapenv:Header xmlns:ns1="http://www.ns1.com"/>
<soapenv:Body>
<ns:request>
<ns:customer>
<ns:id>123</ns:id>
<ns:name type="NCHZ">John Brown</ns:name>
</ns:customer>
</ns:request>
</soapenv:Body>
</soapenv:Envelope>
当我使用以下 xquery / xpath 获得<ns:request>
元素时。
declare namespace soapenv="http://schemas.xmlsoap.org/soap/envelope/"; declare namespace ns="http://example.com/ns"; //soapenv:Envelope/soapenv:Body/ns:request
结果将是
<ns:request xmlns:ns="http://example.com/ns" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<ns:customer>
<ns:id>123</ns:id>
<ns:name type="NCHZ">John Brown</ns:name>
</ns:customer>
</ns:request>
为什么在xmlns:ns="http://example.com/ns" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
元素中添加了<ns:request>
属性,尽管该属性在主xml文件中不存在?以及如何解决?
答案 0 :(得分:1)
您需要了解名称空间在XDM数据模型中的工作方式。每个元素节点都有一组范围内的命名空间(prefix-uri)绑定,这些绑定是通过查看祖先元素中的所有命名空间声明而获得的。当元素节点被序列化时,所有作用域内的名称空间都被序列化为名称空间声明属性,因为处理器不知道它们中的哪些是必需的。
在您的情况下,需要一个名称空间(ns)(因为它在元素名称中使用),而另一个则不需要(在任何地方都没有使用)。
在XSLT(2.0+)中,可以使用<xsl:copy>
和copy-namespaces='no'
来摆脱未使用的名称空间。但是XPath始终为您提供输入节点不变:因此,如果元素在输入中具有两个作用域内的命名空间,则它在输出中仍将具有两个作用域内的命名空间,当元素被序列化时,这些可见。 >
答案 1 :(得分:1)
您可以通过使用xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
和XQuery中的文档构造函数来摆脱范围内但未使用的命名空间declare copy-namespaces no-preserve
,例如
declare copy-namespaces no-preserve, no-inherit;
declare namespace soapenv="http://schemas.xmlsoap.org/soap/envelope/";
declare namespace ns="http://example.com/ns";
document {
//soapenv:Envelope/soapenv:Body/ns:request
}
https://xqueryfiddle.liberty-development.net/gWcDMes
这样,结果将是
<ns:request xmlns:ns="http://example.com/ns">
<ns:customer>
<ns:id>123</ns:id>
<ns:name type="NCHZ">John Brown</ns:name>
</ns:customer>
</ns:request>