<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Dengues Studio: Google Group:http://groups.google.com/group/dengues; QQ Group:24885404.
    解析一個XML文件有很多方法,最常用的就是Dom4j,和JDOM.這個我們就是講使用Xalan來解析一個XML文件.
    先有個xml文件如下:
    <?xml version="1.0" encoding="UTF-8"?>
    <a:main xmlns="test0" xmlns:a="testt" xmlns:b="test2">
        
    <a:node>
            
    <a:nodeA1>A1</a:nodeA1>
            
    <a:nodeA2>
                
    <b:nodeB>B1</b:nodeB>
                
    <b:nodeB>B2</b:nodeB>
            
    </a:nodeA2>
        
    </a:node>
        
    <node>
            
    <nodeD/>
        
    </node>
    </a:main> 
    這個一個簡單的xml文件.但是我們現(xiàn)在要用xpath來查找
    "/a:main/node"
    一般你是一個很復雜的表達式,這個xpath是經(jīng)過簡化的.簡化的代碼你可以使用如下:
     1 private static String simplifyXPathExpression(String xpathExpression) {
     2 
     3         Perl5Matcher matcher = new Perl5Matcher();
     4 
     5         Perl5Compiler compiler = new Perl5Compiler();
     6 
     7         Pattern pattern = null;
     8         try {
     9             pattern = compiler.compile("(.*)/\\s*\\w+\\s*(/(\\.\\.|parent))(.*)");
    10         } catch (MalformedPatternException e) {
    11             ExceptionHandler.process(e);
    12         }
    13 
    14         Perl5Substitution substitution = new Perl5Substitution("$1$4", Perl5Substitution.INTERPOLATE_ALL);
    15 
    16         int lengthOfPreviousXPath = 0;
    17 
    18         do {
    19             lengthOfPreviousXPath = xpathExpression.length();
    20             if (matcher.matches(xpathExpression, pattern)) {
    21                 xpathExpression = Util.substitute(matcher, pattern, substitution, xpathExpression, Util.SUBSTITUTE_ALL);
    22             }
    23         } while (xpathExpression.length() != lengthOfPreviousXPath);
    24 
    25         return xpathExpression;
    26     }
    這里使用的org.apache.oro.text.regex包里面的類.
    現(xiàn)在就開始解析一個XML文件:在Dengues 項目中的org.dengues.commons.jdk.xpath.ComplexXPathUsedXalan類.
     1 public ComplexXPathUsedXalan(String xmlFilename) {
     2         xmlInput = new File(xmlFilename);
     3         if (!xmlInput.exists()) {
     4             throw new RuntimeException("Specified file does not exist!");
     5         }
     6         try {
     7             DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
     8             docFactory.setNamespaceAware(true);
     9             DocumentBuilder builder = docFactory.newDocumentBuilder();
    10             document = builder.parse(xmlInput);
    11             initLastNodes(document.getDocumentElement());
    12             prefixToNamespace.put(XMLConstants.XML_NS_PREFIX, XMLConstants.XML_NS_URI);
    13         } catch (ParserConfigurationException e) {
    14             e.printStackTrace();
    15         } catch (IOException e) {
    16             e.printStackTrace();
    17         } catch (SAXException exception) {
    18             exception.printStackTrace();
    19         }
    20         XPathFactory factory = XPathFactory.newInstance();
    21         xPath = factory.newXPath();
    22         xPath.setNamespaceContext(getNamespaceContext());
    23     }
    這是類的構(gòu)造函數(shù).這里要注意的幾個地方就是:1.第8行設置這個DocFactory支持Namespace.這里一定要設置否則你將不能找所需要的節(jié)點.
    2.在第12行,此前我新建了一個Map用來存儲Prefix和Namespace的對應關系:
    1 private final Map<String, String> prefixToNamespace = new HashMap<String, String>();
    在12行就是講XML對應Namespace設置進去.
    3.第11行,它的作用的就是取出所有的Prefix和Namespace.代碼如下:
     1 private void initLastNodes(Node node) {
     2         NodeList childNodes = node.getChildNodes();
     3         int length = childNodes.getLength();
     4         int type = node.getNodeType();
     5         if (type == Node.ELEMENT_NODE) {
     6             setPrefixToNamespace(node);
     7         }
     8         for (int i = 0; i < length; i++) {
     9             Node item = childNodes.item(i);
    10             if (item.getChildNodes().getLength() > 0) {
    11                 initLastNodes(item);
    12             }
    13         }
    14     }
    15 
    16     /**
    17      * DOC qzhang Comment method "setPrefixToNamespace".
    18      * 
    19      * @param node
    20      */
    21     private void setPrefixToNamespace(Node node) {
    22         NamedNodeMap nnm = node.getAttributes();
    23         for (int i = 0; i < nnm.getLength(); i++) {
    24             Node attr = nnm.item(i);
    25             String aname = attr.getNodeName();
    26             boolean isPrefix = aname.startsWith(XMLConstants.XMLNS_ATTRIBUTE + ":");
    27             if (isPrefix || aname.equals(XMLConstants.XMLNS_ATTRIBUTE)) {
    28                 int index = aname.indexOf(':');
    29                 String p = isPrefix ? aname.substring(index + 1) : XMLConstants.NULL_NS_URI;
    30                 prefixToNamespace.put(p, attr.getNodeValue());
    31             }
    32         }
    33     }
    這樣的就可以去到當前XML的所有Prefix的所有節(jié)點.
    4.其實去Prefix和Namepace還由另外的API:com.sun.org.apache.xml.interal.utils.PrefixResloverDefault,你可以使用它:
    1  PrefixResolverDefault resolverDefault = new PrefixResolverDefault(document.getDocumentElement());
    2        String namespace = resolverDefault.getNamespaceForPrefix(prefix);
    你可以使用這種方法.但是我覺得這種方法在大部分情況下解決不了問題.原因:(1)當前你只有document的根結(jié)點.也就是說它只能得到根結(jié)點定義的Namespace.(2)當根結(jié)點也使用了Namespace的話(a:main),解析就有問題.
    5.構(gòu)造函數(shù)的22行設置一個NamespaceContext,代碼如下:
     1 private NamespaceContext getNamespaceContext() {
     2         return new NamespaceContext() {
     3 
     4             public String getNamespaceURI(String prefix) {
     5                 String namespaceForPrefix = getNamespaceForPrefix(prefix);
     6                 return namespaceForPrefix;
     7 
     8             }
     9 
    10             public java.util.Iterator getPrefixes(String val) {
    11                 return null;
    12             }
    13 
    14             public String getPrefix(String uri) {
    15                 return null;
    16             }
    17         };
    18     }
    19 
    20     /**
    21      * DOC qzhang Comment method "getNamespaceForPrefix".
    22      * 
    23      * @param prefix
    24      * @return
    25      */
    26     protected String getNamespaceForPrefix(String prefix) {
    27         String namespace = prefixToNamespace.get(prefix);
    28         if (namespace != null) {
    29             return namespace;
    30         }
    31         return getDefaultNamespace();
    32     }
    33 
    34     private String getDefaultNamespace() {
    35         Node parent = document.getDocumentElement();
    36         int type = parent.getNodeType();
    37         if (type == Node.ELEMENT_NODE) {
    38             NamedNodeMap nnm = parent.getAttributes();
    39             for (int i = 0; i < nnm.getLength(); i++) {
    40                 Node attr = nnm.item(i);
    41                 String aname = attr.getNodeName();
    42                 if (aname.equals(XMLConstants.XMLNS_ATTRIBUTE)) {
    43                     return attr.getNodeValue();
    44                 }
    45             }
    46         }
    47         return XMLConstants.NULL_NS_URI;
    48     }
    這個總要就是取Namespace值,但是當你輸入Prefix不在Map里面的時候,它將取默認的Namespace,也就是在getDefaultNamespace().
    現(xiàn)在就是最后要提供一個API:
     1 public Object parseXPath(String expression, QName name) {
     2         try {
     3             expression = addDefaultPrefix(expression);
     4             XPathExpression xexpr = xPath.compile(expression);
     5             Object cd = xexpr.evaluate(getDocumnent(), name);
     6             return cd;
     7         } catch (XPathExpressionException e) {
     8             e.printStackTrace();
     9         }
    10         return null;
    11     }
    12 
    13     private String addDefaultPrefix(String xPathExpression) {
    14         if (XMLConstants.NULL_NS_URI.equals(getDefaultNamespace())) {
    15             return xPathExpression;
    16         } else {
    17             StringBuilder expr = new StringBuilder();
    18             String[] split = xPathExpression.split("/");
    19             for (String string : split) {
    20                 if (!string.equals(""&& string.indexOf(':'== -1 && string.indexOf('.'== -1) {
    21                     expr.append(XMLConstants.DEFAULT_NS_PREFIX + ":");
    22                 }
    23                 expr.append(string + "/");
    24             }
    25             if (split.length > 0) {
    26                 expr.deleteCharAt(expr.length() - 1);
    27             }
    28             return expr.toString();
    29         }
    30     }

    這個就是提供的解析xpath表達是的接口.大家會看到了要執(zhí)行一個添加addDefaultPrefix()的函數(shù),它的作用就是在
    當存在默認Namespace的時候,添加一個默認的Prefix.這樣的問題解決了.
    再看看測試的代碼:
     1 private static void testXPath() {
     2         ComplexXPathUsedXalan complexXPath = new ComplexXPathUsedXalan("c:/SimpleNamespace.xml");
     3         String expression = "/a:main/node";
     4         try {
     5             NodeList nodes = (NodeList) complexXPath.parseXPath(expression, XPathConstants.NODESET);
     6             System.out.println("length: " + nodes.getLength());
     7             for (int i = 0; i < nodes.getLength(); i++) {
     8                 Node item = nodes.item(i);
     9                 System.out.println("Name:" + item.getNodeName() + " value:" + item.getNodeValue());
    10             }
    11         } catch (Exception e) {
    12             e.printStackTrace();
    13         }
    14     }
    這樣就可以得到打印結(jié)果:
    1 length: 1
    2 Name:node value:null
    就是這樣了.歡迎大家指正.



    Dengues論壇(http://groups.google.com/group/dengues/),一個很好的Eclipse開發(fā)者樂園.

    Feedback

    # re: [Dengues]關于使用XPath的勸解.帶有Namespace的.  回復  更多評論   

    2007-11-06 16:46 by zDevil(Dengues Studio)
    不好意思,標題都寫錯了,應該是講解.^_^!

    # re: [Dengues]關于使用XPath的勸解.帶有Namespace的.  回復  更多評論   

    2007-11-06 17:41 by li
    恰好今天在項目中也用到dom4j和jaxen,不過在Xpath時候遇到不能能解析命名空間的的問題,沒有好的辦法就去掉了命名空間,呵呵
    以后重新試試

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導航:
     
    Dengues Studio: Google Group:http://groups.google.com/group/dengues; QQ Group:24885404.
    主站蜘蛛池模板: 国产成人在线观看免费网站| 亚洲精品成人片在线观看| 亚洲国产欧美一区二区三区| 全部免费毛片在线| 久久精品视频免费播放| 在线观看日本亚洲一区| 丝袜熟女国偷自产中文字幕亚洲| 免费无码成人AV在线播放不卡| 亚洲国产成人精品无码一区二区| 嫩草视频在线免费观看| 中文字幕在线观看免费| 亚洲中文字幕日本无线码| 国产亚洲精品高清在线| 黄页网站在线观看免费高清| 黄色毛片视频免费| 亚洲国产精品无码久久久| 亚洲国产精品成人一区| 国拍在线精品视频免费观看| 国产无遮挡色视频免费观看性色| 亚洲AV成人无码天堂| 亚洲无人区一区二区三区| 噼里啪啦电影在线观看免费高清| 久久国产精品免费| 亚洲国产午夜精品理论片在线播放| 久久精品国产亚洲麻豆| 国产a不卡片精品免费观看| **真实毛片免费观看| 丰满人妻一区二区三区免费视频| 亚洲va久久久久| 好爽又高潮了毛片免费下载| 免费h视频在线观看| 特级毛片A级毛片100免费播放| 亚洲一级免费视频| 亚洲国产精品成人久久| 亚洲成A人片在线观看中文 | 亚洲福利一区二区精品秒拍| 亚洲精品成人图区| 久久久久久亚洲精品不卡| 日韩激情无码免费毛片| 色se01短视频永久免费| 十九岁在线观看免费完整版电影|