byterat

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            54 隨筆 :: 0 文章 :: 15 評論 :: 0 Trackbacks

          #

          正則表達式語法 
           

          正則表達式是一種文本模式,包括普通字符(例如,a 到 z 之間的字母)和特殊字符(稱為“元字符”)。模式描述在搜索文本時要匹配的一個或多個字符串。

          正則表達式示例
           
          表達式  匹配 
          /^\s*$/
           匹配空行。
           
          /\d{2}-\d{5}/
           驗證由兩位數字、一個連字符再加 5 位數字組成的 ID 號。
           
          /<\s*(\S+)(\s[^>]*)?>[\s\S]*<\s*\/\1\s*>/
           匹配 HTML 標記。
           

          下表包含了元字符的完整列表以及它們在正則表達式上下文中的行為:

           
          字符  說明 
          \
           將下一字符標記為特殊字符、文本、反向引用或八進制轉義符。例如,“n”匹配字符“n”。“\n”匹配換行符。序列“\\”匹配“\”,“\(”匹配“(”。
           
          ^
           匹配輸入字符串開始的位置。如果設置了 RegExp 對象的 Multiline 屬性,^ 還會與“\n”或“\r”之后的位置匹配。
           
          $
           匹配輸入字符串結尾的位置。如果設置了 RegExp 對象的 Multiline 屬性,$ 還會與“\n”或“\r”之前的位置匹配。
           
          *
           零次或多次匹配前面的字符或子表達式。例如,zo* 匹配“z”和“zoo”。* 等效于 {0,}。
           
          +
           一次或多次匹配前面的字符或子表達式。例如,“zo+”與“zo”和“zoo”匹配,但與“z”不匹配。+ 等效于 {1,}。
           
          ?
           零次或一次匹配前面的字符或子表達式。例如,“do(es)?”匹配“do”或“does”中的“do”。? 等效于 {0,1}。
           
          {n}
           n 是非負整數。正好匹配 n 次。例如,“o{2}”與“Bob”中的“o”不匹配,但與“food”中的兩個“o”匹配。
           
          {n,}
           n 是非負整數。至少匹配 n 次。例如,“o{2,}”不匹配“Bob”中的“o”,而匹配“foooood”中的所有 o。“o{1,}”等效于“o+”。“o{0,}”等效于“o*”。
           
          {n,m}
           M 和 n 是非負整數,其中 n <= m。匹配至少 n 次,至多 m 次。例如,“o{1,3}”匹配“fooooood”中的頭三個 o。'o{0,1}' 等效于 'o?'。注意:您不能將空格插入逗號和數字之間。
           
          ?
           當此字符緊隨任何其他限定符(*、+、?、{n}、{n,}、{n,m})之后時,匹配模式是“非貪心的”。“非貪心的”模式匹配搜索到的、盡可能短的字符串,而默認的“貪心的”模式匹配搜索到的、盡可能長的字符串。例如,在字符串“oooo”中,“o+?”只匹配單個“o”,而“o+”匹配所有“o”。
           
          .
           匹配除“\n”之外的任何單個字符。若要匹配包括“\n”在內的任意字符,請使用諸如“[\s\S]”之類的模式。
           
          (pattern)
           匹配 pattern 并捕獲該匹配的子表達式??梢允褂?$0…$9 屬性從結果“匹配”集合中檢索捕獲的匹配。若要匹配括號字符 ( ),請使用“\(”或者“\)”。
           
          (?:pattern)
           匹配 pattern 但不捕獲該匹配的子表達式,即它是一個非捕獲匹配,不存儲供以后使用的匹配。這對于用“or”字符 (|) 組合模式部件的情況很有用。例如,'industr(?:y|ies) 是比 'industry|industries' 更經濟的表達式。
           
          (?=pattern)
           執行正向預測先行搜索的子表達式,該表達式匹配處于匹配 pattern 的字符串的起始點的字符串。它是一個非捕獲匹配,即不能捕獲供以后使用的匹配。例如,'Windows (?=95|98|NT|2000)' 匹配“Windows 2000”中的“Windows”,但不匹配“Windows 3.1”中的“Windows”。預測先行不占用字符,即發生匹配后,下一匹配的搜索緊隨上一匹配之后,而不是在組成預測先行的字符后。
           
          (?!pattern)
           執行反向預測先行搜索的子表達式,該表達式匹配不處于匹配 pattern 的字符串的起始點的搜索字符串。它是一個非捕獲匹配,即不能捕獲供以后使用的匹配。例如,'Windows (?!95|98|NT|2000)' 匹配“Windows 3.1”中的 “Windows”,但不匹配“Windows 2000”中的“Windows”。預測先行不占用字符,即發生匹配后,下一匹配的搜索緊隨上一匹配之后,而不是在組成預測先行的字符后。
           
          x|y
           匹配 x 或 y。例如,'z|food' 匹配“z”或“food”。'(z|f)ood' 匹配“zood”或“food”。
           
          [xyz]
           字符集。匹配包含的任一字符。例如,“[abc]”匹配“plain”中的“a”。
           
          [^xyz]
           反向字符集。匹配未包含的任何字符。例如,“[^abc]”匹配“plain”中的“p”。
           
          [a-z]
           字符范圍。匹配指定范圍內的任何字符。例如,“[a-z]”匹配“a”到“z”范圍內的任何小寫字母。
           
          [^a-z]
           反向范圍字符。匹配不在指定的范圍內的任何字符。例如,“[^a-z]”匹配任何不在“a”到“z”范圍內的任何字符。
           
          \b
           匹配一個字邊界,即字與空格間的位置。例如,“er\b”匹配“never”中的“er”,但不匹配“verb”中的“er”。
           
          \B
           非字邊界匹配。“er\B”匹配“verb”中的“er”,但不匹配“never”中的“er”。
           
          \cx
           匹配 x 指示的控制字符。例如,\cM 匹配 Control-M 或回車符。x 的值必須在 A-Z 或 a-z 之間。如果不是這樣,則假定 c 就是“c”字符本身。
           
          \d
           數字字符匹配。等效于 [0-9]。
           
          \D
           非數字字符匹配。等效于 [^0-9]。
           
          \f
           換頁符匹配。等效于 \x0c 和 \cL。
           
          \n
           換行符匹配。等效于 \x0a 和 \cJ。
           
          \r
           匹配一個回車符。等效于 \x0d 和 \cM。
           
          \s
           匹配任何空白字符,包括空格、制表符、換頁符等。與 [ \f\n\r\t\v] 等效。
           
          \S
           匹配任何非空白字符。與 [^ \f\n\r\t\v] 等效。
           
          \t
           制表符匹配。與 \x09 和 \cI 等效。
           
          \v
           垂直制表符匹配。與 \x0b 和 \cK 等效。
           
          \w
           匹配任何字類字符,包括下劃線。與“[A-Za-z0-9_]”等效。
           
          \W
           與任何非單詞字符匹配。與“[^A-Za-z0-9_]”等效。
           
          \xn
           匹配 n,此處的 n 是一個十六進制轉義碼。十六進制轉義碼必須正好是兩位數長。例如,“\x41”匹配“A”。“\x041”與“\x04”&“1”等效。允許在正則表達式中使用 ASCII 代碼。
           
          \num
           匹配 num,此處的 num 是一個正整數。到捕獲匹配的反向引用。例如,“(.)\1”匹配兩個連續的相同字符。
           
          \n
           標識一個八進制轉義碼或反向引用。如果 \n 前面至少有 n 個捕獲子表達式,那么 n 是反向引用。否則,如果 n 是八進制數 (0-7),那么 n 是八進制轉義碼。
           
          \nm
           標識一個八進制轉義碼或反向引用。如果 \nm 前面至少有 nm 個捕獲子表達式,那么 nm 是反向引用。如果 \nm 前面至少有 n 個捕獲,則 n 是反向引用,后面跟有字符 m。如果兩種前面的情況都不存在,則 \nm 匹配八進制值 nm,其中 n 和 m 是八進制數字 (0-7)。
           
          \nml
           當 n 是八進制數 (0-3),m 和 l 是八進制數 (0-7) 時,匹配八進制轉義碼 nml。
           
          \un
           匹配 n,其中 n 是以四位十六進制數表示的 Unicode 字符。例如,\u00A9 匹配版權符號 (?)。
           

          posted @ 2007-05-17 10:48 比特鼠 閱讀(7541) | 評論 (0)編輯 收藏

          package com.sunrise.ocs.webservice.unicom.test;

          import java.io.File;
          import java.io.StringWriter;
          import java.util.HashMap;
          import java.util.Iterator;

          import javax.xml.parsers.DocumentBuilderFactory;

          import org.apache.log4j.Logger;
          import org.dom4j.Document;
          import org.dom4j.DocumentHelper;
          import org.dom4j.Element;
          import org.dom4j.XPath;
          import org.dom4j.io.SAXReader;

          import com.sun.org.apache.xml.internal.serialize.OutputFormat;
          import com.sun.org.apache.xml.internal.serialize.XMLSerializer;

          public class TestDom4j {
           private static final Logger log = Logger.getLogger(TestDom4j.class);

           private static long bt;

           public static void main(String[] args) {
            String strXml = "";
            int b = 0;
            String file1 = "xml/CreateUserRequest.xml";
            String file2 = "xml/CancelUserRequest.xml";
            if(b==0){
             bt = System.currentTimeMillis();
             strXml = xmlFile2String(file1);
             if (log.isDebugEnabled()) {
              log.debug("\nxmlFile2String() use time: "
                + (System.currentTimeMillis() - bt) + " millis\n");
             }
            }else{
             bt = System.currentTimeMillis();
             strXml = xmlFile2String2(file1);
             if (log.isDebugEnabled()) {
              log.debug("\nxmlFile2String2() use time: "
                + (System.currentTimeMillis() - bt) + " millis\n");
             }
            }

            if(b==0){
             bt = System.currentTimeMillis();
             findElement4XPath1(strXml);
             if (log.isDebugEnabled()) {
              log.debug("\nfindElement4XPath1() use time: "
                + (System.currentTimeMillis() - bt) + " millis\n");
             }
            }else{
             bt = System.currentTimeMillis();
             findElement4XPath2(strXml);
             if (log.isDebugEnabled()) {
              log.debug("\nfindElement4XPath2() use time: "
                + (System.currentTimeMillis() - bt) + " millis\n");
             } 
             
            }
           }

           public static void findElement4XPath1(String xml) {
            try {
             String str = delNamespace4Pattern(xml);
             Document doc = DocumentHelper.parseText(str);
             Element e = (Element) doc.selectSingleNode("http://CreateUserRequest/RequestMessage/MessageHeader");
             if (e != null) {
              Iterator iter = e.elementIterator();
              while (iter.hasNext()) {
               Element sub = (Element) iter.next();
               log.debug("\n" + sub.getText() + "\n");
              }
             }
             
             /* 讀取屬性的例子
             List childNodes = doc.selectNodes("http://Config/Child/ChildNode");
                   for(Object obj:childNodes) {
                       Node childNode = (Node)obj;
                       String name = childNode.valueOf("@name"); //讀取屬性
                       String text = childNode.getText();
                   }
                   */

             
            } catch (Exception e) {
             e.printStackTrace();
            }
           }
           public static void findElement4XPath2(String xml) {
            try {
             Document doc = DocumentHelper.parseText(xml);
             Element root = doc.getRootElement();
             
             HashMap map = new HashMap();
             map.put("tns", "   XPath x = doc.createXPath("http://tns:CreateUserRequest/tns:RequestMessage/tns:MessageHeader");
             x.setNamespaceURIs(map);
             
             Element e = (Element) x.selectSingleNode(doc);
             if (e != null) {
              Iterator iter = e.elementIterator();
              while (iter.hasNext()) {
               Element sub = (Element) iter.next();
               if (log.isDebugEnabled()) {
                log.debug("\n" + sub.getText() + "\n");
               }
              }
             }
            } catch (Exception e) {
             e.printStackTrace();
            }
           }

           public static Document xml2Document(String xml) {
            try {
             return DocumentHelper.parseText(xml);
            } catch (Exception e) {
             e.printStackTrace();
            }
            return null;
           }

           public static String xmlFile2String(String xmlFile) {
            try {
             return new SAXReader().read(new File(xmlFile)).asXML();
            } catch (Exception e) {
             e.printStackTrace();
            }
            return null;
           }
           
           //讀取xml文件為xml串
           public static String xmlFile2String2(String xmlFile) {
            try {
             org.w3c.dom.Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xmlFile); 
             OutputFormat format = new OutputFormat(document);
             //format.setEncoding("UTF-8");
             StringWriter stringOut = new StringWriter();
             XMLSerializer serial = new XMLSerializer(stringOut, format);
             serial.asDOMSerializer();
             serial.serialize(document.getDocumentElement());
             return stringOut.toString();
            } catch (Exception e) {
             e.printStackTrace();
            }
            return "";
           }
           
           
           public static String delNamespace4Pattern(String xml){
            String result = "";
            try {
             result = xml.replaceFirst("xmlns([^ ]*)=([^ ]*)http([^>^\"]*)\"", "");
            } catch (Exception e) {
             e.printStackTrace();
            }
            return result;
            
           }

           

          }

          posted @ 2007-05-17 10:46 比特鼠 閱讀(210) | 評論 (0)編輯 收藏

          package com.sunrise.ocs.webservice.unicom.test;

          import java.io.File;
          import java.io.StringReader;
          import java.io.StringWriter;

          import javax.xml.parsers.DocumentBuilder;
          import javax.xml.parsers.DocumentBuilderFactory;

          import org.w3c.dom.Document;
          import org.w3c.dom.Element;
          import org.w3c.dom.Node;
          import org.xml.sax.InputSource;

          import com.sun.org.apache.xml.internal.serialize.OutputFormat;
          import com.sun.org.apache.xml.internal.serialize.XMLSerializer;

          public class TestDom {
           
           //將xml串轉換為document
           public static Document xml2Document(String xml) {
            Document doc = null;
            try {
             DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
             doc = builder.parse(new InputSource(new StringReader(xml)));
            } catch (Exception e) {
             e.printStackTrace();
            }
            return doc;
           }
           
           //將xml文件串轉換為document
           public static Document xmlFile2Document(String xmlFile) {
            Document doc = null;
            try {
             DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
             doc = builder.parse(new File(xmlFile));
            } catch (Exception e) {
             e.printStackTrace();
            }
            return doc;
           }
           
           //刪除命名空間: xmlns="..."
           public static String delNamespace(String xml) {
            String result = xml;
            try {
             Document doc = xml2Document(xml);
             Element root = doc.getDocumentElement();
             root.removeAttribute("xmlns");
             result = asXml(doc);
            } catch (Exception e) {
             e.printStackTrace();
            }
            return result;
           }
           
           //將doc轉換為xml串
           public static String asXml(Document doc) {
            String strxml = "";
            try {
             OutputFormat format = new OutputFormat(doc);
             // format.setEncoding("UTF-8");
             StringWriter stringOut = new StringWriter();
             XMLSerializer serial = new XMLSerializer(stringOut, format);
             serial.asDOMSerializer();
             serial.serialize(doc.getDocumentElement());
             strxml = stringOut.toString();
            } catch (Exception e) {
             e.printStackTrace();
            }
            return strxml;
           }
           
           //將node轉換為xml串
           public static String asXml(Node node, Document doc) {
            String strxml = "";
            try {
             OutputFormat format = new OutputFormat(doc);
             // format.setEncoding("UTF-8");
             StringWriter stringOut = new StringWriter();
             XMLSerializer serial = new XMLSerializer(stringOut, format);
             serial.asDOMSerializer();
             serial.serialize((Element)node);
             strxml = stringOut.toString();
            } catch (Exception e) {
             e.printStackTrace();
            }
            return strxml;
           }
          }

          posted @ 2007-05-17 10:10 比特鼠 閱讀(288) | 評論 (0)編輯 收藏

          vi 是visual edit 的縮寫
          文本編輯器是所有計算機系統中最常用的一種工具。UNIX下的編輯器有ex,sed和vi等,其中,使用最為廣泛的是vi,而vi命令繁多,論壇里好像這方面的總結不多,以下稍做總結,以資共享!渴望更正和補充!

          進入vi的命令
          vi filename :打開或新建文件,并將光標置于第一行首
          vi +n filename :打開文件,并將光標置于第n行首
          vi + filename :打開文件,并將光標置于最后一行首
          vi +/pattern filename:打開文件,并將光標置于第一個與pattern匹配的串處
          vi -r filename :在上次正用vi編輯時發生系統崩潰,恢復filename
          vi filename....filename :打開多個文件,依次進行編輯

          移動光標類命令
          h :光標左移一個字符
          l :光標右移一個字符
          space:光標右移一個字符
          Backspace:光標左移一個字符
          k或Ctrl+p:光標上移一行
          j或Ctrl+n :光標下移一行
          Enter :光標下移一行
          w或W :光標右移一個字至字首
          b或B :光標左移一個字至字首
          e或E :光標右移一個字至字尾
          ) :光標移至句尾
          ( :光標移至句首
          }:光標移至段落開頭
          { :光標移至段落結尾
          nG:光標移至第n行首
          n+:光標下移n行
          n-:光標上移n行
          n$:光標移至第n行尾
          H :光標移至屏幕頂行
          M :光標移至屏幕中間行
          L :光標移至屏幕最后行
          0:(注意是數字零)光標移至當前行首
          $:光標移至當前行尾

          屏幕翻滾類命令
          Ctrl+u:向文件首翻半屏
          Ctrl+d:向文件尾翻半屏
          Ctrl+f:向文件尾翻一屏
          Ctrl+b;向文件首翻一屏
          nz:將第n行滾至屏幕頂部,不指定n時將當前行滾至屏幕頂部。

          插入文本類命令
          i :在光標前
          I :在當前行首
          a:光標后
          A:在當前行尾
          o:在當前行之下新開一行
          O:在當前行之上新開一行
          r:替換當前字符
          R:替換當前字符及其后的字符,直至按ESC鍵
          s:從當前光標位置處開始,以輸入的文本替代指定數目的字符
          S:刪除指定數目的行,并以所輸入文本代替之
          ncw或nCW:修改指定數目的字
          nCC:修改指定數目的行

          刪除命令
          ndw或ndW:刪除光標處開始及其后的n-1個字
          do:刪至行首
          d$:刪至行尾
          ndd:刪除當前行及其后n-1行
          x或X:刪除一個字符,x刪除光標后的,而X刪除光標前的
          Ctrl+u:刪除輸入方式下所輸入的文本

          搜索及替換命令
          /pattern:從光標開始處向文件尾搜索pattern
          ?pattern:從光標開始處向文件首搜索pattern
          n:在同一方向重復上一次搜索命令
          N:在反方向上重復上一次搜索命令
          :s/p1/p2/g:將當前行中所有p1均用p2替代
          :n1,n2s/p1/p2/g:將第n1至n2行中所有p1均用p2替代
          :g/p1/s//p2/g:將文件中所有p1均用p2替換

          選項設置
          all:列出所有選項設置情況
          term:設置終端類型
          ignorance:在搜索中忽略大小寫
          list:顯示制表位(Ctrl+I)和行尾標志($)
          number:顯示行號
          report:顯示由面向行的命令修改過的數目
          terse:顯示簡短的警告信息
          warn:在轉到別的文件時若沒保存當前文件則顯示NO write信息
          nomagic:允許在搜索模式中,使用前面不帶“\”的特殊字符
          nowrapscan:禁止vi在搜索到達文件兩端時,又從另一端開始
          mesg:允許vi顯示其他用戶用write寫到自己終端上的信息

          最后行方式命令
          :n1,n2 co n3:將n1行到n2行之間的內容拷貝到第n3行下
          :n1,n2 m n3:將n1行到n2行之間的內容移至到第n3行下
          :n1,n2 d :將n1行到n2行之間的內容刪除
          :w :保存當前文件
          :e filename:打開文件filename進行編輯
          :x:保存當前文件并退出
          :q:退出vi
          :q!:不保存文件并退出vi
          :!command:執行shell命令command
          :n1,n2 w!command:將文件中n1行至n2行的內容作為command的輸入并執行之,若不指定n1,n2,則表示將整個文件內容作為command的輸入
          :r!command:將命令command的輸出結果放到當前行

          寄存器操作
          "?nyy:將當前行及其下n行的內容保存到寄存器?中,其中?為一個字母,n為一個數字
          "?nyw:將當前行及其下n個字保存到寄存器?中,其中?為一個字母,n為一個數字
          "?nyl:將當前行及其下n個字符保存到寄存器?中,其中?為一個字母,n為一個數字
          "?p:取出寄存器?中的內容并將其放到光標位置處。這里?可以是一個字母,也可以是一個數字
          ndd:將當前行及其下共n行文本刪除,并將所刪內容放到1號刪除寄存器中。


          進入vi
          vi test
          離開vi
          :q! 離開vi,并放棄剛在緩沖區內編輯的內容。
             :wq 將緩沖區內的資料寫入磁盤中,并離開vi。
             :ZZ 同wq
          同wq
          :w 將緩沖區內的資料寫入磁盤中,但并不離開vi。
            :q 離開vi,若文件被修改過,則會被要求確認是否放棄修改的內容,此指令可與: w 配合使用。
          Vi 的操作模式
          Vi 提供兩種操作模式:
          輸入模式(insert mode)
          指令模式(command mode)
          當使用者進入vi后,既處于指令模式下,此刻鍵入任何字元皆被視為指令。

          輸入模式:a(append) 游標之后加入資料。
          A 該行之末加入資料
          i (insert) 游標之前加入資料
          I 該行之首加入資料
          o (open) 新增一行與該行之下供輸入資料
          O 新增一行與該行之上供輸入資料

          指令模式:B      移至該行第一個字符,若光標在該行第一字符則光標移至上一行第一字符。
             b    由游標所在位置之前一個字串的第一個字元
               cc 刪除整行,修改整行的內容。
               D      以行為單位,刪除游標在內后面的所有字符。
          db 刪除該行光標前字符
               dd 刪除該行
               de 刪除自光標開始后面的字符
               d加字符   刪除光標所在位置至字符之間的單
               E      移至該行最后字符,若光標在該行最后字符則光標移至下一行最后字符
           e      由游標所在位置至該字串的最后一個字元
               G 移至該檔案的最后一行 
               h 向前移一個字元
          j 向下移一個字元
          k 向上移一個字元
          0 移至該行之首
          M 移至視窗的中間那行
          L 移至視窗的最后一行
               l 向后移一個字符
          0 由游標所在位置該行的第一個字元
          nG 移至該檔案的第n行
          n+ 自游標所在位置向后移n行至該行的第一字符
          n- 自游標所在位置向前移n行至該行的第一字符
          R 進入取代狀態,直到《ESC》為止
          s 刪除游標所在字元,并進入取代模式直到《ESC》
          S 刪除游標所在之該行資料,并進入輸入模式直到《ESC》
          w 由游標所在位置之下一個字串的第一個字元
          x 刪除游標所在該字元。
          X 刪除游標所在之前一字元。
          r 用接于此指令之后的字元取代(replace)游標所在字元
          yy yank整行,使游標所在該行復制到記憶體緩沖區
          顯示該行之行號、檔案名稱、檔案中最末之行號、游標所在行號占
          總行號之百分比
          $ 由游標所在位置至該行的最后一個字元。
          ) 由游標所在位置至下一個句子的第一個字元。
          ( 由游標所在位置至該句子的第一個字元。
          {  由游標所在位置至該段落的最后一個字元。
          } 由游標所在位置至該段落的第一個字元

          yank和delete可將指定的資料復制到記憶體緩沖區,而藉有put指令可將緩沖區內的資料復制到熒幕上
          例如:搬移一行 :在該行執行dd
          游標移至目的地
          執行p
          復制一行 :在該行執行yy
          游標移至目的地
          執行p
          視窗移動:
          視窗往下卷一頁
          視窗往上卷一頁
          視窗往下卷半頁
          視窗往上卷半頁
          視窗往下卷一行
          視窗往上卷一行
          刪除、復制及修改指令介紹:
          d(delete)、c(change)和y(yank)這一類的指令在vi 中的指令格式為:
          operation+scope=command
          (運算子)(范圍)
          運算子:
          d 刪除指令。刪除資料,但會將刪除資料復制到記憶體緩沖區。
          y 將資料(字組、行列、句子或段落)復制到緩沖區。
          p 放置(put)指令,與d和y配合使用??蓪⒆詈骴elete或yank的資料放置于游標所在位置之行列下。
          c 修改(change)指令,類似delete于insert的組合。刪除一個字組、句子等資料,并插入新鍵入的




          posted @ 2007-05-15 11:33 比特鼠 閱讀(255) | 評論 (0)編輯 收藏

          1、使用JdbcTemplate的execute()方法執行SQL語句

          代碼

          2、如果是UPDATE或INSERT,可以用update()方法。
          代碼

          3、帶參數的更新
          代碼

          代碼

          4、使用JdbcTemplate進行查詢時,使用queryForXXX()等方法
          代碼

          代碼

          代碼

          代碼

          JdbcTemplate將我們使用的JDBC的流程封裝起來,包括了異常的捕捉、SQL的執行、查詢結果的轉換等等。spring大量使用Template Method模式來封裝固定流程的動作,XXXTemplate等類別都是基于這種方式的實現。
          除了大量使用Template Method來封裝一些底層的操作細節,spring也大量使用callback方式類回調相關類別的方法以提供JDBC相關類別的功能,使傳統的JDBC的使用者也能清楚了解spring所提供的相關封裝類別方法的使用。

          JDBC的PreparedStatement

          代碼

          代碼

          代碼

          在getUser(id)里面使用UserRowMapper

          代碼

          網上收集
          org.springframework.jdbc.core.PreparedStatementCreator 返回預編譯SQL 不能于Object[]一起用

          代碼

          1.增刪改
          org.springframework.jdbc.core.JdbcTemplate 類(必須指定數據源dataSource)
          代碼


          代碼

          org.springframework.jdbc.core.PreparedStatementSetter 接口 處理預編譯SQL
          代碼

          2.查詢JdbcTemplate.query(String,[Object[]/PreparedStatementSetter],RowMapper/RowCallbackHandler)
          org.springframework.jdbc.core.RowMapper 記錄映射接口 處理結果集
          代碼

          org.springframework.jdbc.core.RowCallbackHandler 記錄回調管理器接口 處理結果集
          代碼

          posted @ 2007-04-11 18:48 比特鼠 閱讀(519) | 評論 (0)編輯 收藏

          制作可執行的JAR文件包及jar命令詳解


          常常在網上看到有人詢問:如何把 java 程序編譯成 .exe 文件。通?;卮鹬挥袃煞N,一種是制作一個可執行的 JAR 文件包,然后就可以像.chm 文檔一樣雙擊運行了;而另一種是使用 JET 來進行 編譯。但是 JET 是要用錢買的,而且據說 JET 也不是能把所有的 Java 程序都編譯成執行文件,性能也要打些折扣。所以,使用制作可執行 JAR 文件包的方法就是最佳選擇了,何況它還能保持 Java 的跨平臺特性。 

          下面就來看看什么是 JAR 文件包吧: 

          1. JAR 文件包 

          JAR 文件就是 Java Archive File,顧名思意,它的應用是與 Java 息息相關的,是 Java 的一種文檔格式。JAR 文件非常類似 ZIP 文件——準確的說,它就是 ZIP 文件,所以叫它文件包。JAR 文件與 ZIP 文件唯一的區別就是在 JAR 文件的內容中,包含了一個 META-INF/MANIFEST.MF 文件,這個文件是在生成 JAR 文件的時候自動創建的。舉個例子,如果我們具有如下目錄結構的一些文件: 

            == 

            `-- test 

              `-- Test.class 

          把它壓縮成 ZIP 文件 test.zip,則這個 ZIP 文件的內部目錄結構為: 

            test.zip 

            `-- test 

              `-- Test.class 

          如果我們使用 JDK 的 jar 命令把它打成 JAR 文件包 test.jar,則這個 JAR 文件的內部目錄結構為: 

            test.jar 

            |-- META-INF 

            |  `-- MANIFEST.MF 

            `-- test 

              `--Test.class 

          2. 創建可執行的 JAR 文件包 

          制作一個可執行的 JAR 文件包來發布你的程序是 JAR 文件包最典型的用法。 

          Java 程序是由若干個 .class 文件組成的。這些 .class 文件必須根據它們所屬的包不同而分級分目錄存放;運行前需要把所有用到的包的根目錄指定給 CLASSPATH 環境變量或者 java 命令的 -cp 參數;運行時還要到控制臺下去使用 java 命令來運行,如果需要直接雙擊運行必須寫 Windows 的批處理文件 (.bat) 或者 Linux 的 Shell 程序。因此,許多人說,Java 是一種方便開發者苦了用戶的程序設計語言。 

          其實不然,如果開發者能夠制作一個可執行的 JAR 文件包交給用戶,那么用戶使用起來就方便了。在 Windows 下安裝 JRE (Java Runtime Environment) 的時候,安裝文件會將 .jar 文件映射給 javaw.exe 打開。那么,對于一個可執行的 JAR 文件包,用戶只需要雙擊它就可以運行程序了,和閱讀 .chm 文檔一樣方便 (.chm 文檔默認是由 hh.exe 打開的)。那么,現在的關鍵,就是如何來創建這個可執行的 JAR 文件包。 

          創建可執行的 JAR 文件包,需要使用帶 cvfm 參數的 jar 命令,同樣以上述 test 目錄為例,命令如下: 

          jar cvfm test.jar manifest.mf test 

          這里 test.jar 和 manifest.mf 兩個文件,分別是對應的參數 f 和 m,其重頭戲在 manifest.mf。因為要創建可執行的 JAR 文件包,光靠指定一個 manifest.mf 文件是不夠的,因為 MANIFEST 是 JAR 文件包的特征,可執行的 JAR 文件包和不可執行的 JAR 文件包都包含 MANIFEST。關鍵在于可執行 JAR 文件包的 MANIFEST,其內容包含了 Main-Class 一項。這在 MANIFEST 中書寫格式如下: 

          Main-Class: 可執行主類全名(包含包名) 

          例如,假設上例中的 Test.class 是屬于 test 包的,而且是可執行的類 (定義了 public static void main(String[]) 方法),那么這個 manifest.mf 可以編輯如下: 

          Main-Class: test.Test <回車>; 

          這個 manifest.mf 可以放在任何位置,也可以是其它的文件名,只需要有 Main-Class: test.Test 一行,且該行以一個回車符結束即可。創建了 manifest.mf 文件之后,我們的目錄結構變為: 

            == 

            |-- test 

            |  `-- Test.class 

            `-- manifest.mf 

          這時候,需要到 test 目錄的上級目錄中去使用 jar 命令來創建 JAR 文件包。也就是在目錄樹中使用“==”表示的那個目錄中,使用如下命令: 

          jar cvfm test.jar manifest.mf test 

          之后在“==”目錄中創建了 test.jar,這個 test.jar 就是執行的 JAR 文件包。運行時只需要使用 java -jar test.jar 命令即可。 

          需要注意的是,創建的 JAR 文件包中需要包含完整的、與 Java 程序的包結構對應的目錄結構,就像上例一樣。而 Main-Class 指定的類,也必須是完整的、包含包路徑的類名,如上例的 test.Test;而且在沒有打成 JAR 文件包之前可以使用 java <類名>; 來運行這個類,即在上例中 java test.Test 是可以正確運行的 (當然要在 CLASSPATH 正確的情況下)。 

          3. jar 命令詳解 

          jar 是隨 JDK 安裝的,在 JDK 安裝目錄下的 bin 目錄中,Windows 下文件名為 jar.exe,Linux 下文件名為 jar。它的運行需要用到 JDK 安裝目錄下 lib 目錄中的 tools.jar 文件。不過我們除了安裝 JDK 什么也不需要做,因為 SUN 已經幫我們做好了。我們甚至不需要將 tools.jar 放到 CLASSPATH 中。 

          使用不帶任何的 jar 命令我們可以看到 jar 命令的用法如下: 

          jar {ctxu}[vfm0M] [jar-文件] [manifest-文件] [-C 目錄] 文件名 ... 

          其中 {ctxu} 是 jar 命令的子命令,每次 jar 命令只能包含 ctxu 中的一個,它們分別表示: 

          -c 創建新的 JAR 文件包 

          -t 列出 JAR 文件包的內容列表 

          -x 展開 JAR 文件包的指定文件或者所有文件 

          -u 更新已存在的 JAR 文件包 (添加文件到 JAR 文件包中) 

          [vfm0M] 中的選項可以任選,也可以不選,它們是 jar 命令的選項參數 

          -v 生成詳細報告并打印到標準輸出 

          -f 指定 JAR 文件名,通常這個參數是必須的 

          -m 指定需要包含的 MANIFEST 清單文件 

          -0 只存儲,不壓縮,這樣產生的 JAR 文件包會比不用該參數產生的體積大,但速度更快 

          -M 不產生所有項的清單(MANIFEST〕文件,此參數會忽略 -m 參數 

          [jar-文件] 即需要生成、查看、更新或者解開的 JAR 文件包,它是 -f 參數的附屬參數 

          [manifest-文件] 即 MANIFEST 清單文件,它是 -m 參數的附屬參數 

          [-C 目錄] 表示轉到指定目錄下去執行這個 jar 命令的操作。它相當于先使用 cd 命令轉該目錄下再執行不帶 -C 參數的 jar 命令,它只能在創建和更新 JAR 文件包的時候可用。   

          文件名 ... 指定一個文件/目錄列表,這些文件/目錄就是要添加到 JAR 文件包中的文件/目錄。如果指定了目錄,那么 jar 命令打包的時候會自動把該目錄中的所有文件和子目錄打入包中。 

          下面舉一些例子來說明 jar 命令的用法: 

          1) jar cf test.jar test 

          該命令沒有執行過程的顯示,執行結果是在當前目錄生成了 test.jar 文件。如果當前目錄已經存在 test.jar,那么該文件將被覆蓋。 

          2) jar cvf test.jar test 

          該命令與上例中的結果相同,但是由于 v 參數的作用,顯示出了打包過程,如下: 

          標明清單(manifest) 

          增加:test/(讀入= 0) (寫出= 0)(存儲了 0%) 

          增加:test/Test.class(讀入= 7) (寫出= 6)(壓縮了 14%) 

          3) jar cvfM test.jar test 

          該命令與 2) 結果類似,但在生成的 test.jar 中沒有包含 META-INF/MANIFEST 文件,打包過程的信息也略有差別: 

          增加:test/(讀入= 0) (寫出= 0)(存儲了 0%) 

          增加:test/Test.class(讀入= 7) (寫出= 6)(壓縮了 14%) 

          4) jar cvfm test.jar manifest.mf test 

          運行結果與 2) 相似,顯示信息也相同,只是生成 JAR 包中的 META-INF/MANIFEST 內容不同,是包含了 manifest.mf 的內容 

          5) jar tf test.jar 

          在 test.jar 已經存在的情況下,可以查看 test.jar 中的內容,如對于 2) 和 3) 生成的 test.jar 分別應該此命令,結果如下; 

          對于 2) 

          META-INF/ 

          META-INF/MANIFEST.MF 

          test/ 

          test/Test.class 

          對于 3) 

          test/ 

          test/Test.class 

          6) jar tvf test.jar 

          除顯示 5) 中顯示的內容外,還包括包內文件的詳細信息,如: 

          0 Wed Jun 19 15:39:06 GMT 2002 META-INF/ 

          86 Wed Jun 19 15:39:06 GMT 2002 META-INF/MANIFEST.MF 

          0 Wed Jun 19 15:33:04 GMT 2002 test/ 

          7 Wed Jun 19 15:33:04 GMT 2002 test/Test.class 

          7) jar xf test.jar 

          解開 test.jar 到當前目錄,不顯示任何信息,對于 2) 生成的 test.jar,解開后的目錄結構如下: 

            == 

            |-- META-INF 

            |  `-- MANIFEST 

            `-- test 

              `--Test.class 

          8) jar xvf test.jar 

          運行結果與 7) 相同,對于解壓過程有詳細信息顯示,如: 

          創建:META-INF/ 

          展開:META-INF/MANIFEST.MF 

          創建:test/ 

          展開:test/Test.class 

          9) jar uf test.jar manifest.mf 

          在 test.jar 中添加了文件 manifest.mf,此使用 jar tf 來查看 test.jar 可以發現 test.jar 中比原來多了一個 manifest。這里順便提一下,如果使用 -m 參數并指定 manifest.mf 文件,那么 manifest.mf 是作為清單文件 MANIFEST 來使用的,它的內容會被添加到 MANIFEST 中;但是,如果作為一般文件添加到 JAR 文件包中,它跟一般文件無異。 

          10) jar uvf test.jar manifest.mf 

          與 9) 結果相同,同時有詳細信息顯示,如: 

          增加:manifest.mf(讀入= 17) (寫出= 19)(壓縮了 -11%) 

          4. 關于 JAR 文件包的一些技巧 

          1) 使用 unzip 來解壓 JAR 文件 

          在介紹 JAR 文件的時候就已經說過了,JAR 文件實際上就是 ZIP 文件,所以可以使用常見的一些解壓 ZIP 文件的工具來解壓 JAR 文件,如 Windows 下的 WinZip、WinRAR 等和 Linux 下的 unzip 等。使用 WinZip 和 WinRAR 等來解壓是因為它們解壓比較直觀,方便。而使用 unzip,則是因為它解壓時可以使用 -d 參數指定目標目錄。 

          在解壓一個 JAR 文件的時候是不能使用 jar 的 -C 參數來指定解壓的目標的,因為 -C 參數只在創建或者更新包的時候可用。那么需要將文件解壓到某個指定目錄下的時候就需要先將這具 JAR 文件拷貝到目標目錄下,再進行解壓,比較麻煩。如果使用 unzip,就不需要這么麻煩了,只需要指定一個 -d 參數即可。如: 

          unzip test.jar -d dest/ 

          2) 使用 WinZip 或者 WinRAR 等工具創建 JAR 文件 

          上面提到 JAR 文件就是包含了 META-INF/MANIFEST 的 ZIP 文件,所以,只需要使用 WinZip、WinRAR 等工具創建所需要 ZIP 壓縮包,再往這個 ZIP 壓縮包中添加一個包含 MANIFEST 文件的 META-INF 目錄即可。對于使用 jar 命令的 -m 參數指定清單文件的情況,只需要將這個 MANIFEST 按需要修改即可。 

          3) 使用 jar 命令創建 ZIP 文件 

          有些 Linux 下提供了 unzip 命令,但沒有 zip 命令,所以需要可以對 ZIP 文件進行解壓,即不能創建 ZIP 文件。如要創建一個 ZIP 文件,使用帶 -M 參數的 jar 命令即可,因為 -M 參數表示制作 JAR 包的時候不添加 MANIFEST 清單,那么只需要在指定目標 JAR 文件的地方將 .jar 擴展名改為 .zip 擴展名,創建的就是一個不折不扣的 ZIP 文件了,如將上一節的第 3) 個例子略作改動: 

          jar cvfM test.zip test
          posted @ 2007-04-11 18:19 比特鼠 閱讀(331) | 評論 (1)編輯 收藏

           

          import java.io.File;

          public class Test {
              
          public static void main(String[] args) {
                   System.out.println(
          "1:"+Thread.currentThread().getContextClassLoader().getResource(""));     

                    System.out.println(
          "2:"+Test.class.getClassLoader().getResource(""));        

                    System.out.println(
          "3:"+ClassLoader.getSystemResource(""));        
                    System.out.println(
          "4:"+Test.class.getResource(""));        
                    System.out.println(
          "5:"+Test.class.getResource("/")); //Class文件所在路徑  
                    System.out.println("6:"+new File("").getAbsolutePath());        
                    System.out.println(
          "7:"+System.getProperty("user.dir"));  
                    
                    String s 
          = ClassLoader.getSystemResource("").getPath();
                    System.out.println(s.substring(
          1));
                    System.out.println(s.substring(
          1).substring(0, s.lastIndexOf("/classes")));

              }

          }
          posted @ 2007-04-04 16:49 比特鼠 閱讀(175) | 評論 (0)編輯 收藏

          dom4j 直接往Element中加入符合格式的xml串!

          下面的代碼直接往root元素插入符合格式的xml串:

          String strXml = "<aaa><bbb></bbb><ccc></ccc></aaa>";
          Document doc = DocumentHelper.createDocument();
          Element??root = doc.getRootElement();
          root.add(DocumentHelper.parseText(strXml).getRootElement());
          posted @ 2007-03-27 16:20 比特鼠 閱讀(489) | 評論 (1)編輯 收藏

          ?public long algo(){
          ????int a = 0;
          ????String b = null;
          ????long st = System.currentTimeMillis();
          ????for (int i = 0; i < 2000000; i++){
          ??????b = Integer.toString(a);
          ????}
          ????long et = System.currentTimeMillis();
          ????return (et - st);
          ??}
          posted @ 2007-03-27 15:11 比特鼠 閱讀(1426) | 評論 (1)編輯 收藏

          玩轉 XPath 和缺省命名空間(Default Namespaces)

          原文出自:http://www.edankert.com/defaultnamespaces.html
          翻譯文出自:http://wakan.blog.51cto.com/blog/59583/7220



          諸如“為什么用 XPath 的表達式進行查詢,卻沒有返回所期望的結果?”的問題通常都與命名空間(NameSpace)有關,而且絕大多數是與缺省命名空間(Default Namespace)有關。本文試圖解釋這個問題并針對三種流行的 XPath 實現給出解決方法:Jaxen、JAXP XPPathFactory 以及 XSLT。
          內容列表
          問題描述
          “前綴-命名空間”映射
          Jaxen 和 Dom4J
          Jaxen 和 XOM
          Jaxen 和 JDOM
          JAXP XPathFactory
          XSLT
          結束語
          資源


          問題描述
          看下述 XML:
          <catalog>
          ? <cd>
          ??? <artist>Sufjan Stevens</artist>
          ??? <title>Illinois</title>
          ??? <src>http://www.sufjan.com/</src>
          ? </cd>
          ? <cd>
          ??? <artist>Stoat</artist>
          ??? <title>Future come and get me</title>
          ??? <src>http://www.stoatmusic.com/</src>
          ? </cd>
          ? <cd>
          ??? <artist>The White Stripes</artist>
          ??? <title>Get behind me satan</title>
          ??? <src>http://www.whitestripes.com/</src>
          ? </cd>
          </catalog>

          ??? 你可以使用“//cd”來得到沒有在任何命名空間中定義的“cd”節點。?


          ??? 現在讓我們來改造這個 XML,讓它的所有元素都屬于 'http://www.edankert.com/examples/' 命名空間中。
          ?
          ??? 為了避免在每個不同的元素前都要加個前綴,我們在根元素上定義通常所說的缺省命名空間。改造后的 XML 如下:
          ?
          <catalog xmlns="
          http://www.edankert.com/examples/ ">
          ? <cd>
          ??? <artist>Sufjan Stevens</artist>
          ??? <title>Illinois</title>
          ??? <src>http://www.sufjan.com/</src>
          ? </cd>
          ? <cd>
          ??? <artist>Stoat</artist>
          ??? <title>Future come and get me</title>
          ??? <src>http://www.stoatmusic.com/</src>
          ? </cd>
          ? <cd>
          ??? <artist>The White Stripes</artist>
          ??? <title>Get behind me satan</title>
          ??? <src>http://www.whitestripes.com/</src>
          ? </cd>
          </catalog>

          ??? 當我們使用與上文相同的 XPath “//cd”,將得不到任何元素。這是因為指定的 XPath 返回的是所有不屬于任何命名空間的“cd”節點,而本例中,所有的“cd”元素都屬于缺省的命名空間“http://www.edankert.com/examples/”。


          “前綴-命名空間”映射
          ??? 為了取出命名空間“http://www.edankert.com/examples/”中的所有“cd”元素,我們需要對 XPath 表達式做一些額外的工作。
          ?
          ??? 為了解決這個問題,XPath 規范允許我們使用 QName 來指定元素或者屬性。QName 可以是元素的直接名稱(形如“element”),或者包含一個前綴(形如“pre:element”)。這個前綴需要映射到一個命名空間的 URI 上。例如,如果把“pre”前綴映射到“http://www.edankert.com/test”上,則通過“pre:element”可以查找出屬于命名空間“http://www.edankert.com/test”的所有 “element”元素。
          ?
          ??? 在本例中,我們把“edx”映射到“'http://www.edankert.com/examples/”命名空間上。通過 XPath“//edx:cd”就可以查找出屬于“'http://www.edankert.com/examples/”命名空間的所有“cd”元素。?
          ?
          ??? XPath 處理器允許設置“前綴-命名空間”的映射,但是,如何去映射,卻要依賴于具體的實現。下文舉例說明 Jaxen (JDOM/dom4j/XOM)、JAXP 以及 XSLT 中是如何進行“前綴-命名空間”的映射的。

          Jaxen 和 Dom4J
          ??? 下述代碼從文件系統讀入一個 XML 文件到 org.dom4j.Document 對象中,并且在 Document 中查找屬于“http://www.edankert.com/examples/”命名空間的所有“cd”元素。
          ?
          try {
          ? SAXReader reader = new SAXReader();
          ? Document document = reader.read( "file:catalog.xml");
          ?
          ? HashMap map = new HashMap();
          ? map.put( "edx", "
          http://www.edankert.com/examples/ ");
          ?
          ? XPath xpath = new Dom4jXPath( "http://edx:cd");
          ? xpath.setNamespaceContext( new SimpleNamespaceContext( map));
          ?
          ? List nodes = xpath.selectNodes( document);
          ?
          ? ...
          ?
          } catch ( JaxenException e) { // An error occurred parsing or executing the XPath ... } catch ( DocumentException e) {
          ? // the document is not well-formed.
          ? ...
          }
          ??? 第一步,創建一個 SAXReader,用來從文件系統中讀取“catalog.xml”并創建一個特定于 Dom4j 的 Document 對象。

          ??? 第二步,對于所有 Jaxen 實現都一樣,就是創建一個 HashMap 對象,用于保存“前綴-命名空間的 URI”的映射。
          ?
          ??? 為了能通過 Dom4j 使用 Jaxen 的 XPath 功能,需要創建一個與 Dom4j 相關的 XPath 對象:Dom4jXPath。創建方法是把 XPath 的表達式(即“//edx:cd”)傳給 Dom4jXPath 的構造方法。
          ?
          ??? 現在,我們已經創建了 XPath 對象,接下來可以把“前綴-命名空間”的映射表傳遞給 XPath 引擎:把這個 HashMap 映射表用 SimpleNamespaceContext 包裝起來。SimpleNamespaceContext 是 Jaxen 的 NamespaceContext 接口的默認實現類。
          ?
          ??? 最后一步就是調用 XPath 對象的 selectNodes() 方法進行查找。并把完整的 Dom4j? Document 對象作為參數傳遞進去。實際上,Document 中的任何結點都可以作為參數。

          Jaxen 和 XOM
          ??? XOM 是基于簡單的 Java DOM APIs 之上的最新工具,它的設計初衷是提供簡單和易學易用的接口。
          ?
          try {
          ? Builder builder = new Builder();
          ? Document document = builder.build( "file:catalog.xml");
          ?
          ? HashMap map = new HashMap();
          ? map.put( "edx", "
          http://www.edankert.com/examples/ ");
          ?
          ? XPath xpath = new XOMXPath( "http://edx:cd");
          ? xpath.setNamespaceContext( new SimpleNamespaceContext( map));
          ?
          ? List nodes = xpath.selectNodes( document);
          ?
          ? ...
          ?
          } catch ( JaxenException e) { // An error occurred parsing or executing the XPath ... } catch ( IOException e) {
          ? // An error occurred opening the document
          ? ...
          } catch ( ParsingException e) {
          ? // An error occurred parsing the document
          ? ...
          }

          ?
          ??? 我們需要創建一個 Builder 對象,從文件系統中讀取“catalog.xml”文件,并創建出與 XOM 相關的 Document 對象。
          ?
          ??? 下一步創建出包含了“前綴-命名空間”映射關系的 HashMap 對象。
          ?
          ??? 我們需要創建一個特定于 XOM 的 XPath 對象:XOMXPath。創建方法是把 XPath 表達式傳遞給構造方法,然后就可以通過 XOM 使用 Jaxen 的 XPath 功能了。
          ?
          ??? 創建完 XPath 對象后,同樣,我們把“前綴-命名空間”的映射表用 SimpleNamespaceContext 對象封裝后,傳遞給 XPath 引擎。
          ?
          ??? 最后調用 XPath 對象的“selectNodes()”方法進行查找,把 XOM Document 對象作為本方法的參數。
          Jaxen 和 JDOM
          ??? JDOM 是第一個提供簡單的 XML 訪問 API 的工具。
          ?
          try {
          ? SAXBuilder builder = new SAXBuilder();
          ? Document document = builder.build( "file:catalog.xml");
          ?
          ? HashMap map = new HashMap();
          ? map.put( "edx", "
          http://www.edankert.com/examples/ ");
          ?
          ? XPath xpath = new JDOMXPath( "http://edx:cd");
          ? xpath.setNamespaceContext( new SimpleNamespaceContext( map));
          ?
          ? List nodes = xpath.selectNodes( document);
          ?
          ? ...
          ?
          } catch ( JaxenException e) { // An error occurred parsing or executing the XPath ... } catch ( IOException e) {
          ? // An error occurred opening the document
          ? ...
          } catch ( JDOMException e) {
          ? // An error occurred parsing the document
          ? ...
          }

          ?
          ??? 首先,通過 SAXBuilder 創建了一個特定于 JDom 的 Document 對象。
          ?
          ??? 接著創建一個特定于 JDOM 的 XPath 對象:JDOMXPath。
          ?
          ??? 然后,把“前綴-命名空間”的映射表(HashMap)用 SimpleNamespaceContext 對象封裝起來,傳遞給 XPath 引擎。
          ?
          ??? 最后調用 XPath 對象的“selectNodes()”方法來進行查找,并把 JDOM 的 Document 對象作為本方法的輸入參數。
          JAXP XPathFactory
          ??? 從 1.3 版起, JAXP 還提供了一種在 XML Object Models 上進行查詢的通用機制。
          ?
          try {
          ?DocumentBuilderFactory domFactory =DocumentBuilderFactory.newInstance();
          ? domFactory.setNamespaceAware( true);
          ?
          ?DocumentBuilder builder = domFactory.newDocumentBuilder();Document document = builder.parse( new InputSource( "file:catalog.xml"));
          ?
          ?XPathFactory factory =XPathFactory.newInstance();
          ?XPath xpath = factory.newXPath();
          ? xpath.setNamespaceContext( new NamespaceContext() {
          ??? public String getNamespaceURI(String prefix) {
          ????? if ( prefix.equals( "edx")) {
          ??????? return "
          http://www.edankert.com/examples/ ";
          ????? } else if ...
          ??????? ...
          ????? }
          ?????
          ????? return XPathConstants.NULL_NS_URI;
          ??? }
          ?
          ??? public String getPrefix(String namespaceURI) {
          ????? if ( namespaceURI.equals( "
          http://www.edankert.com/examples/ ")) {
          ??????? return "edx";
          ????? } else if ...
          ??????? ...
          ????? }?
          ???
          ????? return null;
          ??? }
          ?
          ??? public Iterator getPrefixes(String namespaceURI) {
          ???? ArrayList list = new ArrayList();
          ???
          ????? if ( namespaceURI.equals( "
          http://www.edankert.com/examples/ ")) {
          ??????? list.add( "edx");
          ????? } else if ...
          ??????? ...
          ????? }
          ???
          ????? return list.iterator();
          ??? }
          ? });
          ?
          ?Object nodes = xpath.evaluate( "http://edx:cd", document.getDocumentElement(),
          ??????????????????????????????? XPathConstants.NODESET);
          ?
          ? ...
          ?
          } catch (ParserConfigurationException e) {
          ? ...
          } catch (XPathExpressionException e) {
          ? ...
          } catch (SAXException e) {
          ? ...
          } catch (IOException e) {
          ? ...
          }

          ??? 首先用 JAXP 的 DocumentBuilderFactory 創建一個org.w3c.dom.Document 對象,確保啟用了 namespace 處理功能。
          ?
          ??? 現在可以通過 XPathFactory 來創建 XPath 對象,并通過 XPath 對象對文檔進行查詢。
          ?
          ??? 為了創建“前綴-命名空間”映射并傳遞給 XPath 引擎,我們需要實現 NamespaceContext 接口,該接口目前還沒有默認實現類。這就意味著要實現 getNamespaceURI、getPrefix 和getPrefixes 方法,并確保這些方法能返回正確的值,包括“xmlns”和“xml”前綴所對應的命名空間的 URI 值。
          ?
          ??? 把我們自己實現的 NamespaceContext 對象傳遞給 XPath 引擎后,就可以通過 evaluate 方法來查詢 XPath 表達式所對應的元素:使用上文中提到的 XPath 表達式,并使用 Document 的根節點作為輸入入參數,并接收一個 NodeList 對象作為返回結果。
          XSLT
          ??? XPath 設計的初衷是用于 XSLT。這也許能解釋“為什么在 XSLT 中定義命名空間的前綴是一件很平常的事”(也許因為 XSLT 也是一個 XML 名詞的緣故吧)。
          ?
          <xsl:stylesheet version="1.1" xmlns:xsl="
          http://www.w3.org/1999/XSL/Transform ">
          ? <xsl:template match="http://edx:cd" xmlns:edx="
          http://www.edankert.com/examples/ ">
          ??? <xsl:apply-templates/>
          ? </xsl:template>
          </xsl:stylesheet>
          ?
          ??? 只需要使用 XML 本身的機制,簡單地為 edx 前綴賦予一個命名空間的 URI 值。
          ?
          ??? 通過與我們的 XPath 表達式“//edx:cd”相匹配的 xsl:template,能得到與上文其他例子相同的輸出結果。

          結束語
          ??? 為了在(缺省)命名空間上使用 XPath 表達式,我們需要指定一個“前綴-命名空間”映射。正如我們所看到的,具體使用什么樣的前綴名稱,是無關緊要的。
          ?
          ??? 同樣的方法,也可以用于查詢那些用其他前綴修飾的元素。這意味著上面的例子對下述 XML 也有效。下述 XML 沒有使用缺省命名空間,而是使用了 examples 作命名空間的前綴:
          ?
          <examples:catalog xmlns:examples="
          http://www.edankert.com/examples/ ">
          ? <examples:cd>
          ??? <examples:artist>Sufjan Stevens</examples:artist>
          ??? <examples:title>Illinois</examples:title>
          ??? <examples:src>http://www.sufjan.com/</examples:src>
          ? </examples:cd>
          ? <examples:cd>
          ??? <examples:artist>Stoat</examples:artist>
          ??? <examples:title>Future come and get me</examples:title>
          ??? <examples:src>http://www.stoatmusic.com/</examples:src>
          ? </examples:cd>
          ? <examples:cd>
          ??? <examples:artist>The White Stripes</examples:artist>
          ??? <examples:title>Get behind me satan</examples:title>
          ??? <examples:src>http://www.whitestripes.com/</examples:src>
          ? </examples:cd>
          </examples:catalog>

          ?
          ??? 使用“//edx:cd”作為 XPath 表達式,使用與前文例子相同的“前綴-命名空間”映射,在這個 XML 上同樣能查詢出屬于“http://www.edankert.com/examples/”命名空間的所有“cd”元素。
          資源
          Extensible Markup Language (XML) 1.0 (Third Edition)
          http://www.w3.org/TR/REC-xml/
          Namespaces in XML
          http://www.w3.org/TR/REC-xml-names/
          XML Path Language (XPath) Version 1.0
          http://www.w3.org/TR/xpath
          XSL Transformations (XSLT) Version 1.0
          http://www.w3.org/TR/xslt
          dom4j
          http://www.dom4j.org/
          XOM
          http://www.xom.nu/
          JDOM
          http://www.jdom.org/
          Jaxen
          http://www.jaxen.org/
          Java 5.0
          http://java.sun.com/j2se/1.5.0/

          posted @ 2007-03-21 10:13 比特鼠 閱讀(1728) | 評論 (1)編輯 收藏

          僅列出標題
          共6頁: 上一頁 1 2 3 4 5 6 下一頁 
          主站蜘蛛池模板: 英山县| 宁波市| 宜黄县| 科技| 麻栗坡县| 牙克石市| 永川市| 维西| 华安县| 白水县| 巴马| 太湖县| 郎溪县| 岳池县| 宝鸡市| 临城县| 杭州市| 靖宇县| 景东| 绥江县| 田林县| 瓦房店市| 甘南县| 道孚县| 古田县| 勐海县| 新丰县| 深泽县| 廉江市| 灵寿县| 郑州市| 中阳县| 平远县| 黄骅市| 安阳县| 晴隆县| 盐津县| 吐鲁番市| 承德县| 芜湖县| 阳谷县|