使用Java解析xml
我正在尝试解析dom元素 要素:使用Java解析xml,java,xml,dom,xpath,Java,Xml,Dom,Xpath,我正在尝试解析dom元素 要素: <?xml version="1.0" encoding="UTF-8"?> <feed xmlns="http://www.w3.org/2005/Atom"> <id>http://X/feed2</id> <title>Sample Feed</title> <entry> <id>http://X/feed2/104</id>
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<id>http://X/feed2</id>
<title>Sample Feed</title>
<entry>
<id>http://X/feed2/104</id>
<title>New Title</title>
</entry>
</feed>
http://X/feed2
进样
http://X/feed2/104
新标题
我正在尝试获取以下条目:
<entry>
<id>http://top.cs.vt.edu/libx2/vsony7@vt.edu/feed2/104</id>
<title>New Title</title>
</entry>
http://top.cs.vt.edu/libx2/vsony7@vt.edu/feed2/104
新标题
我正在使用xpath解析xml:
“/atom:feed/atom:entry[atom:id=\”http://X/feed2/104\“]”
但是,当我试图解析Dom元素时,我遇到了一个异常。有人能推荐一种在Java中实现这一点的简单方法吗
请查看我的完整代码:
public static parseXml() {
String externalEntryIdUrl = "http://theta.cs.vt.edu/~rupen/thirtylibapps/137";
String externalFeedUrl = StringUtils.substringBeforeLast(externalEntryIdUrl, "/");
try {
URL url = new URL(externalFeedUrl);
InputStream externalXml = new BufferedInputStream(url.openStream());
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(externalXml);
Element externalFeed = doc.getDocumentElement();
String atomNameSpace = "xmlns:atom=\"http://www.w3.org/2005/Atom\"";
String entryIdPath = String.format("//%s:entry[%s:id=%s]", atomNameSpace, atomNameSpace, externalEntryIdUrl);
Element externalEntry = (Element) XPathSupport.evalNode(entryIdPath, externalFeed);
} catch (Exception ex) {
// Throw exception
}
}
static synchronized Node evalNode(String xpathExpr, Node node) {
NodeList result = evalNodeSet(xpathExpr, node);
if (result.getLength() > 1)
throw new Error ("More than one node for:" + xpathExpr);
else if (result.getLength() == 1)
return result.item(0);
else
return null;
}
static synchronized NodeList evalNodeSet(String xpathExpr, Node node) {
try {
static XPath xpath = factory.newXPath();
xpath.setNamespaceContext(context);
static NamespaceContext context = new NamespaceContext() {
private Map<String, String> prefix2URI = new HashMap<String, String>();
{
prefix2URI.put("libx", "http://libx.org/xml/libx2");
prefix2URI.put("atom", "http://www.w3.org/2005/Atom");
}
};
XPathExpression expr = xpath.compile(xpathExpr);
Object result = expr.evaluate(node, XPathConstants.NODESET);
return (NodeList)result;
} catch (XPathExpressionException xpee) {
throw new Error ("An xpath expression exception: " + xpee);
}
}
publicstaticparsexml(){
字符串ExternalEntryDurl=”http://theta.cs.vt.edu/~rupen/thirtylibapps/137”;
字符串externalFeedUrl=StringUtils.substringBeforeLast(externalentrydurl,“/”);
试一试{
URL URL=新URL(externalFeedUrl);
InputStream externalXml=新的BufferedInputStream(url.openStream());
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
DocumentBuilder db=dbf.newDocumentBuilder();
Document doc=db.parse(externalXml);
Element externalFeed=doc.getDocumentElement();
字符串atomNameSpace=“xmlns:atom=\”http://www.w3.org/2005/Atom\"";
String entrydpath=String.format(“//%s:entry[%s:id=%s]”,atomNameSpace,atomNameSpace,ExternalEntryDurl);
元素externalEntry=(元素)XPathSupport.evalNode(EntryDiPath,externalFeed);
}捕获(例外情况除外){
//抛出异常
}
}
静态同步节点evalNode(字符串xpathExpr,节点节点){
节点列表结果=evalNodeSet(xpathExpr,节点);
if(result.getLength()>1)
抛出新错误(“多个节点用于:“+xpathExpr”);
else if(result.getLength()==1)
返回结果。项(0);
其他的
返回null;
}
静态同步节点列表evalNodeSet(字符串xpathExpr,节点节点){
试一试{
静态XPath=factory.newXPath();
setNamespaceContext(context);
静态名称空间上下文=新名称空间上下文(){
私有映射prefix2URI=新HashMap();
{
prefix2URI.put(“libx”http://libx.org/xml/libx2");
prefix2URI.put(“原子”http://www.w3.org/2005/Atom");
}
};
XPathExpression expr=xpath.compile(xpathExpr);
对象结果=expr.evaluate(节点,XPathConstants.NODESET);
返回(节点列表)结果;
}捕获(XPathExpressionException xpee){
抛出新错误(“xpath表达式异常:“+xpee”);
}
}
严重:>>java.lang.Error:xpath表达式异常:javax.xml.xpath.XPathExpressionException您可以使用SAX解析器。
下面是一个SAX解析的示例您可以利用
名称空间上下文
执行以下操作:
package forum9059851;
import java.io.FileInputStream;
import java.util.Iterator;
import javax.xml.namespace.NamespaceContext;
import javax.xml.xpath.*;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
public class Demo {
public static void main(String[] args) {
try {
XPathFactory xpf = XPathFactory.newInstance();
XPath xp = xpf.newXPath();
xp.setNamespaceContext(new MyNamespaceContext());
XPathExpression xpe = xp.compile("ns:feed/ns:entry");
FileInputStream xmlStream = new FileInputStream("src/forum9059851/input.xml");
InputSource xmlInput = new InputSource(xmlStream);
Element result = (Element) xpe.evaluate(xmlInput, XPathConstants.NODE);
System.out.println(result);
} catch (Exception ex) {
// Throw exception
}
}
private static class MyNamespaceContext implements NamespaceContext {
public String getNamespaceURI(String prefix) {
if("ns".equals(prefix)) {
return "http://www.w3.org/2005/Atom";
}
return null;
}
public String getPrefix(String namespaceURI) {
return null;
}
public Iterator getPrefixes(String namespaceURI) {
return null;
}
}
}
如果您不想重新发明轮子,不想解析提要数据,我建议您使用已经可用的库。我发现从URL获取xml时没有设置名称空间感知 所以 这样做可以解决我的问题。如果不这样做,在解析xml时为XPathFactory实例设置名称空间上下文(如我的示例所示)本身就不起作用。“我得到一个异常”是一个
TooManyKittensException
?汤姆猫黛丝。还有别的吗?也许您可以与我们共享(即复制/粘贴)。您是否在Java代码中将前缀atom
与命名空间关联(注册了命名空间)http://www.w3.org/2005/Atom“
?您必须执行此操作(推荐)或使用类似以下操作:/*/*[local-name()='entry'][*[local-name()='id']='http://X/feed2/104]“
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);