java中通过xpath处理含有命名空间

声明:以下的测试是用的jdk1.4.2,xalan7.0对于如下xml文档片断: <ML:MREML xmlns:ML="MREML">
<EnvelopEntity>
<EnvelopID>GUID2006102000002</EnvelopID>
<EnvelopVersion>1.0.1R</EnvelopVersion>
<ExchangeTime>2006-10-25 13:12:10</ExchangeTime>
<SendFrom>
<SFID>SOBEY_NEWS</SFID>
<SFDescription>SOBEY新闻系统</SFDescription>
</SendFrom>
<SendTo>
<STID>DAYANG_MAM</STID>
<STDescription>DAYANG媒资系统</STDescription>
</SendTo>
<Priority>2</Priority>
<EntityInfo>
<EntityID>REQUEST_ID_01</EntityID>
<EntityType>4</EntityType>
</EntityInfo>
<EntityInfo>
<EntityID>节目GUID</EntityID>
<EntityType>3</EntityType>
</EntityInfo>
<EntityInfo>
<EntityID>管理信息实体ID</EntityID>
<EntityType>2</EntityType>
</EntityInfo>
</EnvelopEntity>
</ML:MREML >
对于上述含有命名空间的xml文档,如果想通过xpath查找EnvelopID的值,有两种方式:1.通过利用xpath的函数local-name()

如上述查找内容的xpath表达式可以写为://*[local-name()='MREML']/EnvelopEntity/EnvelopID/text()

2.通过在java程序中处理上述文档的命名空间是定义的,如果要使xpath表达式能正确地被解析需要在java程序中建立起prefix和uri二者的映射关系
public static Node parseXPath(String expression, Object obj, QName qname)
throws Exception {
javax.xml.xpath.XPath xpath = javax.xml.xpath.XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(getNamespaceContext());
if (qname.equals(XPathConstants.NODE))
return (Node) xpath.evaluate(expression, obj, qname);
return null;
}

public static NamespaceContext getNamespaceContext() throws Exception {
return new NamespaceContext() {
public String getNamespaceURI(String prefix) {
/*
// 一种方式:
//这里可以采用配置文件的方式,先将所需要使用的xmlNamespace配置好,
//采用注册的方式供应用使用,这种方式效率应该高一些,不用每次都要从文档中提取namespace
//不过没有第二种方便
String uri;
if (prefix.equalsIgnoreCase("ML"))
uri = "MREML";
else if (prefix.equalsIgnoreCase("RE"))
uri = "http://herry.com.cn";
else if (prefix.equalsIgnoreCase("RID"))
uri = "ResourceID";
else if (prefix.equalsIgnoreCase("RUI"))
uri = "ResourceUniqueID";
else if (prefix.equalsIgnoreCase("RMDI"))
uri = "ResourceMetaDataInfo";
else
uri = null;
System.out.println(ParseXMLUtil.class + "::getNamespaceURI:prefix= " + prefix);
return uri;
*/
/*
// 另外一种方式: 通过PrefixResolver来提取出prefix和Namespace的对应关系
final PrefixResolver resolver =
new PrefixResolverDefault(doc.getDocumentElement());

return resolver.getNamespaceForPrefix(prefix);

*/

// Dummy implementation - not used!
public java.util.Iterator getPrefixes(String val) {
return null;
}

// Dummy implemenation - not used!
public String getPrefix(String uri) {
return null;
}
};
}
若要查找ResourceUniqueID的值,则xpath应该书写为://ML:MREML/ML:ResourceEntity/RMDI:ResourceMetaDataInfo/RMDI:ResourceID/RUI:ResourceUniqueID/text()

这里的ML(prefix)和URI(MERML)等已经通过

对于含有默认命名空间地文档如果采用NamespaceContext的方式,即将prefix和uri已经映射起来,如对于以下的文档:
<MREML xmlns="MREML"><ResourceEntity >
<ResourceMetaDataInfo>
<ResourceID xmlns="ResourceID">
<RUI:ResourceUniqueID xmlns:RUI="ResourceUniqueID">节目GUID</RUI:ResourceUniqueID>
<UserDefID>UserDefID填写节目代码</UserDefID>
</ResourceID>
<Title>
<ResourceName>911新闻素材</ResourceName>
</Title>
<ResourceType>1</ResourceType>
<Subject>
<KeyWords>911 袭击</KeyWords>
</Subject>
<Description>
<ContentDescription>美国遭遇911袭击现场30S画面及同期声素材</ContentDescription>
<Column>
<ColumnName>今日世界</ColumnName>
</Column>
</Description>
<Date>
<CreateDate>2006-10-25 13:12:10</CreateDate>
</Date>
<Format>
<TotalLength>00:04:35:12</TotalLength>
<NumberofElements>2</NumberofElements>
<MarkPoint>
<StartPoint>00:00:00:05</StartPoint>
<EndPoint>00:04:35:10</EndPoint>
</MarkPoint>
</Format>
</ResourceMetaDataInfo>
</ResourceEntity>
</MREML>

若要查找ResourceUniqueID的值,则xpath应该书写为://ML:MREML/ML:ResourceEntity/RMDI:ResourceMetaDataInfo/RMDI:ResourceID/RUI:ResourceUniqueID/text()

这里的ML(prefix)和URI(MERML)等已经通过
if (prefix.equalsIgnoreCase("ML"))
uri = "MREML";
else if (prefix.equalsIgnoreCase("RE"))
uri = "http://herry.com.cn";
else if (prefix.equalsIgnoreCase("RID"))
uri = "ResourceID";
else if (prefix.equalsIgnoreCase("RUI"))
uri= "ResourceUniqueID";
else if (prefix.equalsIgnoreCase("RMDI"))
uri = "ResourceMetaDataInfo";
else
uri = null;
映射。

其中的ML和RMDI都是default namespace,它的作用范围包含它的子元素,直至有新的default namespace出现为止。而namespace只对它自身起作用。如将上述文档中:<ResourceMetaDataInfo>
<ResourceID xmlns="ResourceID">
改为:
<RMDI:ResourceMetaDataInfo xmlns:RMDI=” ResourceMetaDataInfo”>
<ResourceID>


</ RMDI:ResourceMetaDataInfo>
查找ResourceUniqueID的值,则xpath应该改为://ML:MREML/ML:ResourceEntity/RMDI:ResourceMetaDataInfo/ResourceID/RUI:ResourceUniqueID/text()

大家也可参考这篇文章:
http://blog.davber.com/2006/09/17/xpath-with-namespaces-in-java/

时间: 2024-10-29 00:37:03

java中通过xpath处理含有命名空间的相关文章

方法-java+中怎样声明一个含有ArrayVolume的接口

问题描述 java+中怎样声明一个含有ArrayVolume的接口 java+中怎样声明一个含有ArrayVolume的接口,含有array(),和volume()两个抽象方法,请给个例子 解决方案 public interface IArrayVolulmn{ public void array(); public void volume(); } 解决方案二: public interface Some { void array(); void volume(); }

如何从代码层防御10大安全威胁中的 Xpath Injection?

普遍性和可检测性: Xpath 注入是 OWASP TOP10 安全威胁中 A1 Injection 中的一种,注入漏洞发生在应用程序将不可信的数据发送到解释器时.虽然注入漏洞很容易通过审查代码发现,但是却不容易在测试中发现. 影响严重: 注入能导致数据丢失或数据破坏.缺乏可审计性或者是拒绝服务.注入漏洞有时候甚至能导致完全主机接管. 从代码层次如何防御: 首先我们先来看一下在 Java 中引用 xpath 需要用的 lib 库: javax.xml.xpath org.jdom.xpath o

java中的spring配置文件中引入context命名空间却不能使用context标签

问题描述 java中的spring配置文件中引入context命名空间却不能使用context标签 myeclipse中spring配置文件的 命名空间 为什么导入了相对应的命名空间但是 相对应的标题 却不能使用 求大神 解决方案 http://zhidao.baidu.com/link?url=CYTl2LDpKwI4j4Dgi2W7vI8OltUewUkwn1A8dW_7-LDXMNPJzc2ieqDzv33rIzF4W2s2Ss5B7SeSsn_UPoGXYqCmZb-kcdotYkwhe

java中的“包”与C#中的“命名空间

Package vs. Namespace 我们知道,重用性(reusebility)是软件工程中一个非常重要的目标.重用,不仅仅指自己所写的软件(代码.组件等等)可以被重复利用:更广义的重用是指不同的人,不同的团队,不同的公司之间可以互相利用别人的成果.另外,对于大型软件,往往是由多个团队共同开发的,这些团队有可能分布于不同的城市.地区.甚至国家.由于这些原因,名字管理成为一个非常重要的因素. 由于C语言本身不提供名字管理的机制(C语言的static命名解决的是可见性问题,这些名字不会输出给外

Java中继承、多态、重载和重写介绍_java

什么是多态?它的实现机制是什么呢?重载和重写的区别在那里?这就是这一次我们要回顾的四个十分重要的概念:继承.多态.重载和重写. 继承(inheritance) 简单的说,继承就是在一个现有类型的基础上,通过增加新的方法或者重定义已有方法(下面会讲到,这种方式叫重写)的方式,产生一个新的类型.继承是面向对象的三个基本特征--封装.继承.多态的其中之一,我们在使用JAVA时编写的每一个类都是在继承,因为在JAVA语言中,java.lang.Object类是所有类最根本的基类(或者叫父类.超类),如果

java中this作为方法名的时候的问题,不知道我把它看成方法名正步正确

问题描述 java中this作为方法名的时候的问题,不知道我把它看成方法名正步正确 如下代码所示, public MyView(Context context) { this(context null); } //this在这里是方法吗,this是一个方法名吗? 解决方案 this用来调用你这个类中定义的一个构造方法 解决方案二: this不是方法名,而是Java中对当前对象的引用.例如当前对象的引用用this,父类对象的引用用super 解决方案三: 一个类中定义两个构造函数,在一个构造函数中

Java中关于XML的API惊鸿一瞥

xml 简单介绍一下Java关于xml的API,这样大家看到了缩写就知道是干什么的了.水平有限,多多包涵. 1.JAXP(Java API for XML Parsing) 2.JAXB(Java API for XML Binding) 3.JAXM(Java API for XML Messaging) 4.JAX-RPC(Java API for XML-RPC) 1.JAXP定义了在Java中使用DOM, SAX, XSLT的通用的接口.这样在你的程序中你只要使用这些通用的接口,当你需要

研究 Java 中 XML 文档模型的特性和性能

xml|性能 Java 中的 XML: 文档模型,第一部分:性能 研究 Java 中 XML 文档模型的特性和性能 文档选项 将此页作为电子邮件发送 最新推荐 Java 应用开发源动力 - 下载免费软件,快速启动开发 级别: 初级 Dennis M. Sosnoski, 总裁, Sosnoski Software Solutions, Inc. 2001 年 9 月 01 日 在本文中,Java 顾问 Dennis Sosnoski 比较几个 Java 文档模型的性能和功能.当选择模型时,无法做

详解Java中的指针、引用及对象的clone

对象|详解 Java语言的一个优点就是取消了指针的概念,但也导致了许多程序员在编程中常常忽略了对象与引用的区别,本文会试图澄清这一概念.并且由于Java不能通过简单的赋值来解决对象复制的问题,在开发过程中,也常常要要应用clone()方法来复制对象.本文会让你了解什么是影子clone与深度clone,认识它们的区别.优点及缺点.看到这个标题,是不是有点困惑:Java语言明确说明取消了指针,因为指针往往是在带来方便的同时也是导致代码不安全的根源,同时也会使程序的变得非常复杂难以理解,滥用指针写成的