XML解析之xsi:nil="true"(续)
这里补充一下对带有name space的时候,应该
com.sun.org.apache.xpath.internal.XPathAPI的不足。由于XpathAPI提供的com.sun.org.apache.xml.internal.utils.PrefixResolver并不能处理各个element自定义的 name space。所以需要对PrefixResolver进行改进。
在 Xpath读取的时候,用一下的方法代替 XPathAPI.getSingleNode()。
我们在用自己定义个MyPrefixResolver作为参数,进行调用。
注意:但name space的值是一样,而定义的名不一样时,被视为同意个name space
<
a
xmlns:aa
="11111"
/>
<
c
xmlns:bb
="11111"
/>
<!--
他们的命名空间是一样的
-->
end thanks
在 Xpath读取的时候,用一下的方法代替 XPathAPI.getSingleNode()。
public
org.w3c.dom.Node getSingleNode(org.w3c.dom.Node node, String xpath,
com.sun.org.apache.xml.internal.utils.PrefixResolver pr)
throws javax.xml.transform.TransformerException {
com.sun.org.apache.xpath.internal.objects.XObject obj
= com.sun.org.apache.xpath.internal.XPathAPI.eval(node, xpath, pr);
return obj.nodelist().item( 0 );
}
com.sun.org.apache.xml.internal.utils.PrefixResolver pr)
throws javax.xml.transform.TransformerException {
com.sun.org.apache.xpath.internal.objects.XObject obj
= com.sun.org.apache.xpath.internal.XPathAPI.eval(node, xpath, pr);
return obj.nodelist().item( 0 );
}
public
class
MyPrefixResolver
implements
com.sun.org.apache.xml.internal.utils.PrefixResolver {
private java.util.Map < String, String > map = new java.util.HashMap < String, String > ();
public TalendPrefixResolver(org.w3c.dom.Node root) {
countNSMap(root);
}
public String getBaseIdentifier() {
return null ;
}
public String getNamespaceForPrefix(String prefix) {
if (prefix.equals( " xml " )) {
return com.sun.org.apache.xml.internal.utils.Constants.S_XMLNAMESPACEURI;
} else {
return map.get(prefix);
}
}
public String getNamespaceForPrefix(String prefix, org.w3c.dom.Node context) {
return getNamespaceForPrefix(prefix);
}
public boolean handlesNullPrefixes() {
return false ;
}
// 遍历XMlfile,获取所有的命名空间的定义,可能这里有点笨,希望有人又跟好的方案
private void countNSMap(org.w3c.dom.Node el) {
if (el.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
org.w3c.dom.NamedNodeMap attris = el.getAttributes();
for ( int i = 0 ; i < attris.getLength(); i ++ ) {
org.w3c.dom.Node attr = attris.item(i);
String aname = attr.getNodeName();
if (aname.startsWith( " xmlns " )) {
int index = aname.indexOf( " : " );
aname = index > 0 ? aname.substring(index + 1 ) : aname;
map.put(aname, attr.getNodeValue());
}
}
}
org.w3c.dom.NodeList nodeList = el.getChildNodes();
for ( int i = 0 ; i < nodeList.getLength(); i ++ ) {
countNSMap(nodeList.item(i));
}
}
}
private java.util.Map < String, String > map = new java.util.HashMap < String, String > ();
public TalendPrefixResolver(org.w3c.dom.Node root) {
countNSMap(root);
}
public String getBaseIdentifier() {
return null ;
}
public String getNamespaceForPrefix(String prefix) {
if (prefix.equals( " xml " )) {
return com.sun.org.apache.xml.internal.utils.Constants.S_XMLNAMESPACEURI;
} else {
return map.get(prefix);
}
}
public String getNamespaceForPrefix(String prefix, org.w3c.dom.Node context) {
return getNamespaceForPrefix(prefix);
}
public boolean handlesNullPrefixes() {
return false ;
}
// 遍历XMlfile,获取所有的命名空间的定义,可能这里有点笨,希望有人又跟好的方案
private void countNSMap(org.w3c.dom.Node el) {
if (el.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
org.w3c.dom.NamedNodeMap attris = el.getAttributes();
for ( int i = 0 ; i < attris.getLength(); i ++ ) {
org.w3c.dom.Node attr = attris.item(i);
String aname = attr.getNodeName();
if (aname.startsWith( " xmlns " )) {
int index = aname.indexOf( " : " );
aname = index > 0 ? aname.substring(index + 1 ) : aname;
map.put(aname, attr.getNodeValue());
}
}
}
org.w3c.dom.NodeList nodeList = el.getChildNodes();
for ( int i = 0 ; i < nodeList.getLength(); i ++ ) {
countNSMap(nodeList.item(i));
}
}
}
注意:但name space的值是一样,而定义的名不一样时,被视为同意个name space


end thanks