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 比特鼠 阅读(7524) | 评论 (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("//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("//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", "http://bme.sunrise.com/unicom/gd");
   XPath x = doc.createXPath("//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 比特鼠 阅读(203) | 评论 (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 比特鼠 阅读(279) | 评论 (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配合使用。可将最后delete或yank的资料放置于游标所在位置之行列下。
c 修改(change)指令,类似delete于insert的组合。删除一个字组、句子等资料,并插入新键入的




posted @ 2007-05-15 11:33 比特鼠 阅读(238) | 评论 (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 比特鼠 阅读(508) | 评论 (0)编辑 收藏

制作可执行的JAR文件包及jar命令详解


常常在网上看到有人询问:如何把 java 程序编译成 .exe 文件。通常回答只有两种,一种是制作一个可执行的 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 比特鼠 阅读(321) | 评论 (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 比特鼠 阅读(167) | 评论 (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 比特鼠 阅读(477) | 评论 (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 比特鼠 阅读(1415) | 评论 (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( "//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( "//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( "//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( "//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="//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 比特鼠 阅读(1713) | 评论 (1)编辑 收藏

仅列出标题
共6页: 上一页 1 2 3 4 5 6 下一页