我在做什么错误的XPath?
问题描述:
我想操纵xsd模式作为一个xml文档,我认为这不应该是一个问题。但面临XPath的麻烦。无论我尝试XPath,它都不会返回任何内容。尝试使用或不使用命名空间,但没有成功。 请帮我理解我做错了什么?我在做什么错误的XPath?
我的XML是:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.mydomain.com" xmlns="http://www.mydomain.com" elementFormDefault="qualified">
<xs:complexType name="Label">
<xs:choice maxOccurs="unbounded" minOccurs="0">
<xs:element name="Listener"/>
</xs:choice>
</xs:complexType>
</xs:schema>
和应用程序代码是:
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setValidating(false);
domFactory.setNamespaceAware(true);
domFactory.setIgnoringComments(true);
domFactory.setIgnoringElementContentWhitespace(true);
try {
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document dDoc = builder.parse("C:/Temp/test.xsd");
// This part works
Node rootNode = dDoc.getElementsByTagName("xs:schema").item(0);
System.out.println(rootNode.getNodeName());
// This part doesn't work
XPath xPath1 = XPathFactory.newInstance().newXPath();
NodeList nList1 = (NodeList) xPath1.evaluate("//xs:schema", dDoc, XPathConstants.NODESET);
System.out.println(nList1.item(0).getNodeName());
// This part doesn't work
XPath xPath2 = XPathFactory.newInstance().newXPath();
NodeList nList2 = (NodeList) xPath2.evaluate("//xs:element", rootNode, XPathConstants.NODESET);
System.out.println(nList2.item(0).getNodeName());
}catch (Exception e){
e.printStackTrace();
}
答
使用XPath.setNamespaceContext设置一个名称空间上下文()。这将xs
前缀绑定到http://www.w3.org/2001/XMLSchema
命名空间。
答
原因是你没有指定什么xs
的含义。 XML解析器必须知道名称空间url,xs
只是一个标识符。
您可以通过下面的代码演示了这个自己:
XPath xPath = XPathFactory.newInstance().newXPath();
SimpleNamespaceContext nsContext = new SimpleNamespaceContext();
nsContext.addNamespace("t", "http://www.w3.org/2001/XMLSchema");
xPath.setNamespaceContext(nsContext);
xPath.evaluate("//t:schema", dDoc, XPathConstants.NODESET);
你可以看到,我现在使用的标识符t
,而不是xs
但只要你使用相同的命名空间URL不要紧。
+2
您应该先导入org.custommonkey.xmlunit.SimpleNamespaceContext或类似的东西,因为JDK不包含'javax.xml的实现.namespace.Namespace'。 – 2010-10-06 13:32:19
答
对您的代码进行了更改。它的工作原理:
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class XPathtest {
public static void main(String[] args) {
DocumentBuilderFactory domFactory = DocumentBuilderFactory
.newInstance();
domFactory.setValidating(false);
domFactory.setNamespaceAware(true);
domFactory.setIgnoringComments(true);
domFactory.setIgnoringElementContentWhitespace(true);
try {
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document dDoc = builder.parse("C:/Temp/test.xsd");
// This part works
Node rootNode = dDoc.getElementsByTagName("xs:schema").item(0);
System.out.println(rootNode.getNodeName());
// This part doesn't work
XPath xPath1 = XPathFactory.newInstance().newXPath();
NamespaceContext nsContext = new NamespaceContext() {
@Override
public String getNamespaceURI(String prefix) {
return "http://www.w3.org/2001/XMLSchema";
}
@Override
public String getPrefix(String namespaceURI) {
return "xs";
}
@Override
public Iterator getPrefixes(String namespaceURI) {
Set s = new HashSet();
s.add("xs");
return s.iterator();
}
};
xPath1.setNamespaceContext((NamespaceContext) nsContext);
NodeList nList1 = (NodeList) xPath1.evaluate("//xs:schema", dDoc,
XPathConstants.NODESET);
System.out.println(nList1.item(0).getNodeName());
// This part doesn't work
// XPath xPath2 = XPathFactory.newInstance().newXPath();
NodeList nList2 = (NodeList) xPath1.evaluate("//xs:element",
rootNode, XPathConstants.NODESET);
System.out.println(nList2.item(0).getNodeName());
} catch (Exception e) {
e.printStackTrace();
}
}
}
然后xPath1.evaluate(“// schema”,...)应该这样做吗? – willcodejavaforfood 2010-08-25 17:58:04
@willcodejavaforfood:No.'// schema'表示没有命名空间下树中的任何'schema'元素。应该是'/ xs:schema' – 2010-08-25 18:14:18
@Ajjandro - 确定这很有意义,谢谢 – willcodejavaforfood 2010-08-25 20:40:16