Sql Server 2005 中有一个 xml 类型的数据,这种数据的用处是很大的!
以Sql server 2005中自带的AdventureWorks为例:
Individual 表的类型为 XML 的 Demographics 列包含如下信息,单个客户的常用人口统计信息(如婚姻状况、子女数目、教
育、职业、拥有的汽车数和爱好)等,但是用户可能不会填写全部信息,而为每个统计数据都建立一列对数据库设计来说是很费事
的! 因此,在调查中使用一个类型为 XML 的列,而不是创建多个列(每个问题一列)并在数据库中将未回答的问题存储为值 NULL。
存储为 XML 的调查信息也可以提供给客户关系管理系统和商业智能系统。
因此,建立xml文档格式的列是很有必要的!
但是:通过jdbc或hibernate读出来的数据还是xml文档类型的,怎样才能取得其中的信息呢? 我想,自己编写一个程序,解析xml文
档,读出其中数据.
我写了一个解析xml文档的程序,这是一个类似于"词法分析器"的程序,但是功能不强,嵌套的xml文档不能分析出来.但是足够满足
功能了.(时间复杂度为n)
java 代码
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- public class AnalyzeAll {
- private int currentLength;
- private int currentPosition;
- private List list;
- private XmlPOJO xp;
- public AnalyzeAll()
- {
- this.setCurrentLength(0);
- this.setCurrentPosition(0);
- this.list = new ArrayList();
- this.xp = new XmlPOJO();
- }
- public void analyze(String xml)
- {
- this.setCurrentLength(xml.length());
- while(true){
- if((this.getCurrentPosition()+2 )>=this.getCurrentLength())
- break;
- if(xml.substring( getCurrentPosition() ,
- getCurrentPosition() + 1).equals("<"))
- {
- xp = new XmlPOJO();
- this.setCurrentPosition(getCurrentPosition()+1);
- analyzeInside( xml , getCurrentPosition() );
- }
- else this.setCurrentPosition(getCurrentPosition()+1);
- }
- this.printInfo();
- }
- private int analyzeInside(String xml,int cPosition)
- {
- boolean flag = true;
- while(true){
- if((this.getCurrentPosition()+2 )>=this.getCurrentLength())
- return 0;
- if(xml.substring(getCurrentPosition(),
- getCurrentPosition() + 1).equals(">"))
- if(flag)
- {
- xp.setElementName(xml.substring(cPosition,
- getCurrentPosition()));
- this.setCurrentPosition(getCurrentPosition()+1);
- this.analyzeProperty(xml, getCurrentPosition());
- return 0;
- }
- else return 0;
- if(xml.substring(getCurrentPosition(),
- getCurrentPosition() + 1).equals(" "))
- flag = false;
- this.setCurrentPosition(this.getCurrentPosition()+1);
- }
- }
- private void analyzeProperty(String xml, int cPosition)
- {
- while(true){
- if((this.getCurrentPosition()+2 )>=this.getCurrentLength())
- break;
- if(xml.substring(getCurrentPosition(),
- getCurrentPosition() + 2).equals("))
- {
- xp.setProperty(xml.substring(cPosition,getCurrentPosition()));
- this.setToList();
- break;
- }
- this.setCurrentPosition(getCurrentPosition()+1);
- }
- while(true){
- if((this.getCurrentPosition()+2 )>=this.getCurrentLength())
- break;
- if(xml.substring(getCurrentPosition(),
- getCurrentPosition() + 1).equals(">"))
- {
- this.setCurrentPosition(getCurrentPosition()+1);
- break;
- }
- this.setCurrentPosition(getCurrentPosition()+1);
- }
- }
- private void setToList()
- {
- list.add(xp);
- }
- private void printInfo()
- {
- Iterator it = list.iterator();
- for(int i = 0 ; i< list.size() ; i++ )
- {
- XmlPOJO xmlpojo = (XmlPOJO)it.next();
- System.out.println("ElementName: "+xmlpojo.getElementName()+", Property: "+xmlpojo.getProperty());
- }
- }
- public int getCurrentLength() {
- return currentLength;
- }
- public void setCurrentLength(int currentLength) {
- this.currentLength = currentLength;
- }
- public int getCurrentPosition() {
- return currentPosition;
- }
- public void setCurrentPosition(int currentPosition) {
- this.currentPosition = currentPosition;
- }
- }
其中使用了一个 XmlPOJO的类,用来保存每条 elementName, property.
java 代码
- public class XmlPOJO {
- private String elementName;
- private String property;
- public String getElementName() {
- return elementName;
- }
- public void setElementName(String elementName) {
- this.elementName = elementName;
- }
- public String getProperty() {
- return property;
- }
- public void setProperty(String property) {
- this.property = property;
- }
- }
最后,使用的xml用例测试
xml 代码
- <IndividualSurvey xmlns=http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/IndividualSurvey><TotalPurchaseYTD>8248.99TotalPurchaseYTD><DateFirstPurchase>2001-07-22ZDateFirstPurchase><BirthDate>1966-04-08ZBirthDate><MaritalStatus>MMaritalStatus><YearlyIncome>75001-100000YearlyIncome><Gender>MGender><TotalChildren>2TotalChildren><NumberChildrenAtHome>0NumberChildrenAtHome><Education>BachelorsEducation><Occupation>ProfessionalOccupation><HomeOwnerFlag>1HomeOwnerFlag><NumberCarsOwned>0NumberCarsOwned><Hobby>GolfHobby><Hobby>Watch TVHobby><CommuteDistance>1-2 MilesCommuteDistance>IndividualSurvey>
得出分析结果:
java 代码
- ElementName: TotalPurchaseYTD, Property: 8248.99
- ElementName: DateFirstPurchase, Property: 2001-07-22Z
- ElementName: BirthDate, Property: 1966-04-08Z
- ElementName: MaritalStatus, Property: M
- ElementName: YearlyIncome, Property: 75001-100000
- ElementName: Gender, Property: M
- ElementName: TotalChildren, Property: 2
- ElementName: NumberChildrenAtHome, Property: 0
- ElementName: Education, Property: Bachelors
- ElementName: Occupation, Property: Professional
- ElementName: HomeOwnerFlag, Property: 1
- ElementName: NumberCarsOwned, Property: 0
- ElementName: Hobby, Property: Golf
- ElementName: Hobby, Property: Watch TV
- ElementName: CommuteDistance, Property: 1-2 Miles
即使是10W字节的xml文档也可以在几毫秒的时间内全部分析完毕!