java中通过xpath处理含有命名空间
声明:以下的测试是用的jdk1.4.2,xalan7.0对于如下xml文档片断:
<ML:MREMLxmlns:ML="MREML">
<EnvelopEntity>
<EnvelopID>GUID2006102000002</EnvelopID>
<EnvelopVersion>1.0.1R</EnvelopVersion>
<ExchangeTime>2006-10-2513: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二者的映射关系
publicstaticNodeparseXPath(Stringexpression,Objectobj,QNameqname)
throwsException{
javax.xml.xpath.XPathxpath=javax.xml.xpath.XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(getNamespaceContext());
if(qname.equals(XPathConstants.NODE))
return(Node)xpath.evaluate(expression,obj,qname);
returnnull;
}
publicstaticNamespaceContextgetNamespaceContext()throwsException{
returnnewNamespaceContext(){
publicStringgetNamespaceURI(Stringprefix){
/*
//一种方式:
//这里可以采用配置文件的方式,先将所需要使用的xmlNamespace配置好,
//采用注册的方式供应用使用,这种方式效率应该高一些,不用每次都要从文档中提取namespace
//不过没有第二种方便
Stringuri;
if(prefix.equalsIgnoreCase("ML"))
uri="MREML";
elseif(prefix.equalsIgnoreCase("RE"))
uri="http://herry.com.cn";
elseif(prefix.equalsIgnoreCase("RID"))
uri="ResourceID";
elseif(prefix.equalsIgnoreCase("RUI"))
uri="ResourceUniqueID";
elseif(prefix.equalsIgnoreCase("RMDI"))
uri="ResourceMetaDataInfo";
else
uri=null;
System.out.println(ParseXMLUtil.class "::getNamespaceURI:prefix=" prefix);
returnuri;
*/
/*
//另外一种方式:通过PrefixResolver来提取出prefix和Namespace的对应关系
finalPrefixResolverresolver=
newPrefixResolverDefault(doc.getDocumentElement());
returnresolver.getNamespaceForPrefix(prefix);
*/
//Dummyimplementation-notused!
publicjava.util.IteratorgetPrefixes(Stringval){
returnnull;
}
//Dummyimplemenation-notused!
publicStringgetPrefix(Stringuri){
returnnull;
}
};
}
若要查找ResourceUniqueID的值,则xpath应该书写为://ML:MREML/ML:ResourceEntity/RMDI:ResourceMetaDataInfo/RMDI:ResourceID/RUI:ResourceUniqueID/text()
这里的ML(prefix)和URI(MERML)等已经通过
对于含有默认命名空间地文档如果采用NamespaceContext的方式,即将prefix和uri已经映射起来,如对于以下的文档:
<MREMLxmlns="MREML"><ResourceEntity>
<ResourceMetaDataInfo>
<ResourceIDxmlns="ResourceID">
<RUI:ResourceUniqueIDxmlns: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-2513: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";
elseif(prefix.equalsIgnoreCase("RE"))
uri="http://herry.com.cn";
elseif(prefix.equalsIgnoreCase("RID"))
uri="ResourceID";
elseif(prefix.equalsIgnoreCase("RUI"))
uri="ResourceUniqueID";
elseif(prefix.equalsIgnoreCase("RMDI"))
uri="ResourceMetaDataInfo";
else
uri=null;
映射。
其中的ML和RMDI都是default namespace,它的作用范围包含它的子元素,直至有新的default namespace出现为止。而namespace只对它自身起作用。如将上述文档中:<ResourceMetaDataInfo>
<ResourceIDxmlns="ResourceID">
改为:
<RMDI:ResourceMetaDataInfoxmlns:RMDI=”ResourceMetaDataInfo”>
<ResourceID>
…
…
</RMDI:ResourceMetaDataInfo>
查找ResourceUniqueID的值,则xpath应该改为://ML:MREML/ML:ResourceEntity/RMDI:ResourceMetaDataInfo/ResourceID/RUI:ResourceUniqueID/text()