Chinaunix首页 | 论坛 | 博客
  • 博客访问: 638218
  • 博文数量: 692
  • 博客积分: 4000
  • 博客等级: 上校
  • 技术积分: 4715
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-17 13:38
文章分类

全部博文(692)

文章存档

2011年(1)

2008年(691)

我的朋友

分类:

2008-10-17 13:49:13

    声明:以下的测试是用的jdk1.4.2,xalan7.0对于如下xml文档片断:


    
        GUID2006102000002
        1.0.1R
        2006-10-25 13:12:10
        
            SOBEY_NEWS
                           SOBEY新闻系统
        

        
            DAYANG_MAM
            DAYANG媒资系统
        

        2
        
            REQUEST_ID_01
            4
        

        
            节目GUID
            3
        

        
            管理信息实体ID
            2
        

    


    对于上述含有命名空间的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 = "";
                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已经映射起来,如对于以下的文档:

        
            
                节目GUID
                UserDefID填写节目代码
            
            <BR>                <ResourceName>911新闻素材</ResourceName><BR>            
            1
            
                911 袭击
            

            
                美国遭遇911袭击现场30S画面及同期声素材
                
                    今日世界
                

            

            
                2006-10-25 13:12:10
            

            
                00:04:35:12
                2
                
                    00:00:00:05
                    00:04:35:10
                

            

        




    若要查找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 = "";
                                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只对它自身起作用。如将上述文档中:
            
改为:

            



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

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

【责编:Chuan】

--------------------next---------------------

阅读(274) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~