Android中如何解析XML文件并获取指定节点的属性值?
解决方案
解析拿不到目标值的核心原因是未处理XML的默认命名空间。示例XML根节点声明了xmlns="urn:oasis:names:tc:opendocument:xmlns:container"默认命名空间,所有不带前缀的子节点都归属这个命名空间,未开启命名空间支持的解析器、或者查找节点时不传对应命名空间,都无法匹配到目标元素。
下面是Java DOM解析的可运行实现:
import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.io.File; public class EpubContainerParse { public static void main(String[] args) throws Exception { // 初始化解析工厂,必须开启命名空间感知 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); // 加载你的container.xml文件 Document document = builder.parse(new File("META-INF/container.xml")); // 定义XML使用的默认命名空间 final String CONTAINER_NS = "urn:oasis:names:tc:opendocument:xmlns:container"; // 按命名空间+标签名定位rootfile节点 NodeList rootFileList = document.getElementsByTagNameNS(CONTAINER_NS, "rootfile"); if (rootFileList.getLength() > 0) { Element rootFileElement = (Element) rootFileList.item(0); // 读取full-path属性值,无前缀属性不属于默认命名空间,直接读取即可 String fullPath = rootFileElement.getAttribute("full-path"); System.out.println(fullPath); // 输出结果:OEBPS/content.opf } } }
其他实现说明
- 如果使用XPath查询,需要先配置命名空间解析器,将上述默认命名空间绑定一个自定义前缀(比如
cont),再执行XPath表达式/cont:container/cont:rootfiles/cont:rootfile/@full-path即可拿到属性值 - 不要尝试用字符串替换删掉xmlns声明的方式绕开命名空间处理,这种方式在XML结构变动、存在多命名空间时极易失效
- 注意:不带前缀的属性不会继承默认命名空间,读取属性时不需要传入命名空间参数,直接调用
getAttribute方法即可。
内容的提问来源于stack exchange,提问作者Ankit Verma
相关产品推荐
相关产品推荐

