声明:以下的测试是用的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/ |