XML解析之xsi:nil="true"(续)

来源:互联网 发布:北京数据分析培训机构 编辑:程序博客网 时间:2024/05/18 16:18
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()。
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);
}
    我们在用自己定义个MyPrefixResolver作为参数,进行调用。
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));
        }
    }
}

       注意:但name space的值是一样,而定义的名不一样时,被视为同意个name space
<xmlns:aa="11111"/>
<xmlns:bb="11111"/><!--他们的命名空间是一样的-->

end thanks