我同样有一个XML
<?xml version="1.0" encoding="UTF-8"?>
<QDTM_IN300301QD ITSVersion="XML_1.0" xmlns="urn:hl7-org:v3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:hl7-org:v3 QDTM_IN300401QD.xsd ">
<controlActEvent classCode="CACT" moodCode="EVN">
<code code="QDTM_TE300401QD">
</code>
<statusCode code="Active" />
<subject contextConductionInd="true" contextControlCode="ON"
typeCode="SUBJ">
<registrationEvent classCode="REG" moodCode="EVN">
<statusCode code="token" />
<subject contextControlCode="AN" typeCode="SBJ">
<testCodeIdentifier classCode="ROL">
<playingTestCodeDetails classCode="ENT"
determinerCode="INSTANCE">
<code code="6399Z" codeSystemName="QTIM" codeSystemVersion="Updated">
<originalText><![CDATA[CBC (includes Differential and Platelets)]]></originalText>
<translation codeSystemName="DOSCATALOGNAMEHTMLENABLED">
<originalText><![CDATA[CBC (includes Differential and Platelets)]]></originalText>
</translation>
</code>
</playingTestCodeDetails>
</testCodeIdentifier>
</subject>
</registrationEvent>
</subject>
</controlActEvent>
</QDTM_IN300301QD>
JAVA CODE:
package com.parse;
import java.io.IOException;
import java.util.Iterator;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
public class ParseXPath {
public String parseXML(String fileName) {
fileName = "D://projects//Draft.xml";
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder;
Document doc;
try {
builder = domFactory.newDocumentBuilder();
doc = builder.parse(fileName);
XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(new NamespaceContext(){public String getNamespaceURI(String prefix) {
return "urn:hl7-org:v3";
}
public String getPrefix(String namespaceURI) {
return null; // we are not using this.
}
public Iterator getPrefixes(String namespaceURI) {
return null; // we are not using this.
}
});
String expr="//QDTM_IN300401QD/controlActEvent/subject/registrationEvent/subject/testCodeIdentifier/playingTestCodeDetails/code/translation[@codeSystemName='DOSCATALOGNAMEHTMLENABLED']/originalText/text()";
String result = xpath.evaluate(expr, doc);
System.out.println("Result --> "+result);
return result;
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XPathExpressionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return fileName;
public static void main(String[] args)
throws ParserConfigurationException, SAXException,
IOException, XPathExpressionException {
ParseBUXpath p = new ParseBUXpath();
p.parseRelatedTestXML("test");
}
}
我在XML中的Namespace中遇到了这个问题。当xml具有&#34; xmlns =&#34; urn:hl7-org:v3&#34;然后xpath查询不会得到我的数据。为了压制我已经在java中编写代码并从XML中删除了该行。
我需要解析XML并获取数据而不从XML中删除命名空间部分。这是一个与xsd相关的问题,还是没有提到xsd?
答案 0 :(得分:1)
您需要在表达式中包含命名空间,命名空间可以替换为&#34;前缀&#34;充当查找完整命名空间uri。
String expr="//prefix:QDTM_IN300401QD/controlActEvent/...."
您使用命名空间映射设置的,请查看https://www.ibm.com/developerworks/library/x-javaxpathapi/index.html和https://xml.apache.org/xalan-j/xpath_apis.html#namespacecontext
如果xml只包含一个命名空间,您还可以尝试在表达式中使用// *:elementname来简单地忽略元素名称所在的命名空间。
查看http://www.w3schools.com/XML/xml_namespaces.asp以了解命名空间的使用方式以及它们解决的问题
答案 1 :(得分:0)
getNamespaceURI
内NamespaceContext
的目的是将源文档中的每个命名空间与唯一的前缀相关联,以便XPath引擎在遇到该前缀时知道元素属于哪个命名空间XPath表达式中的字符串。这里的前缀不需要匹配源XML中相同URI的前缀(如果有的话);它只需要提供从前缀到正确命名空间的映射。
所以,如果你要写这样的表达式:
//p:QDTM_IN300301QD/p:controlActEvent/p:subject/p:registrationEvent/p:subject
/p:testCodeIdentifier/p:playingTestCodeDetails/p:code
/p:translation[@codeSystemName='DOSCATALOGNAMEHTMLENABLED']
/p:originalText/text()"
...然后你会像这样编写相应的getNamespaceURI
:
public String getNamespaceURI(String prefix) {
if ("p".equals(prefix)) {
return "urn:hl7-org:v3";
}
return null;
}
这就是引擎知道在遇到urn:hl7-org:v3
前缀时p
命名空间中查找元素的方式,这就是重点。 Othwerwise,引擎如何知道您不想在 no 名称空间中使用名为QDTM_IN300301QD
的元素?或者在其他名称空间中具有该名称的元素?
请注意,前缀名称是任意的;它可以是你想要的任何东西,只要它是独一无二的。也就是说,如果您的文档中有其他名称空间,那么您需要修改getNamespaceURI
以了解这些名称空间并为每个名称空间分配唯一的前缀。
这是一个完整的(最小)示例:
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse("Draft.xml");
XPath xpath = XPathFactory.newInstance().newXPath();
NamespaceContext ctx = new NamespaceContext() {
public String getNamespaceURI(String prefix) {
if ("p".equals(prefix)) {
return "urn:hl7-org:v3";
}
return null;
}
public String getPrefix(String uri) {
throw new UnsupportedOperationException();
}
public Iterator getPrefixes(String uri) {
throw new UnsupportedOperationException();
}
};
xpath.setNamespaceContext(ctx);
XPathExpression expr = xpath.compile("//p:QDTM_IN300301QD/p:controlActEvent" +
"/p:subject/p:registrationEvent" +
"/p:subject/p:testCodeIdentifier/p:playingTestCodeDetails/p:code" +
"/p:translation[@codeSystemName='DOSCATALOGNAMEHTMLENABLED']" +
"/p:originalText/text()");
System.out.println("[" + expr.evaluate(doc, XPathConstants.STRING));