进入旧版 | 服务项目 | 成功案例 | 联系方式 | 过客留言 | 友情链接
   
设为首页
加入收藏
联系我们
网站首页 | 新闻资讯 | 操作系统 | 办公软件 | 网络软件 | 工具软件 | 媒体动画 | 网页制作 | 网站开发 | 程序开发 | 平面设计
Photoshop视频教程 | Word入门 | Flash入门 | JScript | VBScript | ASP | PHP | ADO | 网页特效 | 3DS MAX6.0命令 | 系统进程
您当前的位置:GOODSGY电脑学习网 -> 网站开发 -> XML/SOAP -> 文章内容  
XPath在无线应用中的实现(下)

  在本文的第一部分中,我们介绍了XPath并讨论了各种各样的从简单到复杂的XPath查询。 通过把XPath查询应用到XML示例文件,我们详细说明了各种重要的XPath定义比如location step、context node、location path、axes和node - test。 我们然后讨论了多个简单查询组合成的复杂的XPath查询。 我们还讨论了无线二进制XML(WBXML)--XML在无线应用领域的对应物--的抽象结构。 最后我们介绍一个简单的XPath处理引擎的设计。

  在这一部分里,我们打算讨论XPath的更进一步的特性--在一个XML文件上执行复杂检索的操作。 我们将讨论谓词或者过滤器查询以及在XPath中的函数的使用。我们将介绍各种的用于处理WSDL和WML的XPath查询。 我们还将增强我们的XPath引擎的功能,使之包括谓词、函数和不同的数据类型。

  过滤查询和谓词

  让我们从一个将返回任何XML文件当中的根节点的简单查询开始:

  ./node()

  我们可以更进一步,使用另一个简单查询,选择根节点的全部的直接子节点:

  ./node()/*

  如果你想要得到所有的是根节点的直接子节点并且只有一个type属性的节点,那么该怎么办呢? 那么就使用下面的这个查询:

  ./node()/*[attribute::type]
 
  在代码段1中,这个查询将返回binding元素。 由此可见,写在方括号之内的代码attribute::query担负一个过滤器的功能。 XPath中的过滤器被称作谓词(predicate),写在方括号内。 一个谓词作用在一个结点集上--在这个例子中,结点集由根节点的所有的直接子节点组成---应用过滤条件(在这里,结点肯定有一个type属性)到结点集上。 产生的结果就是一个经过过滤的结点集。

  谓词可以从简单到很复杂。 也许XPath谓词的简单形式就像下面的查询中的只是一个数字,返回根元素的第二个子节点(message元素):

  ./node()/*[2]

  查询语句./node()/message[attribute::name="TotalBill"]/text() 将寻找根元素的一个属性name值为TotalBill的特定的message子节点。 查询将返回特定的message元素的所有文本结点。 这个查询将返回代码段1中两个message元素中的第二个。

  XPath 函数

  假定你想要回答下面对代码段1中的WSDL文件所提出的问题:

  1. 最后一个operation元素的name属性的值是什么?

  2.定义元素有多少个message子元素?

  3. 根元素的第一个子元素的名称是什么?

  last()函数

  last()函数将总是指向结点集的最后一个结点。 下面的这个查询,当被应用于代码段1中的WSDL文件的时候,将返回第二message元素(即 名称是TotalBill的message元素):

  ./node()/message[last()]

  注意下面的这条查询也返回相同的message元素:

  ./node()/message[2]

  这两个查询之间唯一的区别就是我们使用数字2来代替last()方法。 事实上在本例中last()函数返回的值就是2(特定location step的结点集中的结点数)。 把这两个相同的查询应用到代码段2中的WSDL文件,这次你会发现两个查询没有返回相同的结果。 代码段2中有三个message元素,所以现在last()函数返回数字3。
注意本讨论中的last()函数总是返回一个数字。

  position()函数

  如果你把下面的这些查询应用到代码段2中的WSDL文件,

  ./node()/message[1]/part

  ./node()/message[2]/part

  ./node()/message[3]/part

  它们将分别返回message元素的第一个、第二个和第三个part子元素。 由此可见节点集中的每个节点都有一个位置。 第一个节点的位置是1,第二个节点的位置是2,以此类推。

  如果你想要得到除第二个以外的所有的message元素,你该怎么办? 你可以使用position()函数取得一个节点的位置。 下面的这条查询将返回代码段2中的第一个和第三个message元素:

  ./node()/message[position()!=2]

  position()函数只是返回指定值所表示的节点的位置。 谓词[position()!=2] 把所有的message元素的位置和2做比较,然后找出位置不是2的节点。
  count()函数
  
  代码段1中的portType元素有多少个message子元素? 数一数你就发现有两个message元素。 在XPath中解决"多少个"这种问题是一个二步的操作。 首先,写一个用来找到你想要统计的所有的子元素的XPath查询。 然后地像下面给出的那样,把 XPath查询传送到count()函数中:

  步骤1: ./node()/message

  步骤2: count(./node()/message)

  count()函数统计XPath查询所得到的节点集中的节点数,并返回这个节点数。

  name()、local-name()和namespace-uri()函数

  如果把下面的查询应用到代码段1中的WSDL文件的话,那么会出现什么情况呢?

  ./node()/*[5]

  它返回根元素的第五个子元素(即service元素)。 service元素本身是一个完整结构,也包含子元素。 因此,这个XPath查询的返回值实际上是一个XML节点而不仅仅是一个元素名。

  name()函数返回XML节点的名称。 例如,下面的查询应用到代码段1中将返回字符串"service":

  name(./node()/*[5])

  同样,下面的查询将返回字符串"wsd:definitions"(使用域名空间前缀的根元素的全名):

  name(./node())

  local-name()和namespace-uri()函数与name()函数类似,除了local-name方法只返回不带域名空间前缀的元素的局部名称,而namespace-uri函数仅仅返回域名空间URI。举例来说,请在代码段1中试验下面的查询:

  local-name(./node())

  namespace-uri(./node())

  第一个查询返回一个字符串" definitions",而第二个查询返回" http://schemas.XMLsoap.org/wsdl/ "。

  String函数

  我们已经知道name()、local-name()和namespace-uri()函数返回字符串。 XPath提供了许多函数用于处理字符串,比如string()、 substring()、substring-before()、 substring-after()、 concat()、starts-with()等等。 下面给出了一个例子来演示一下如何使用string()函数:

  string(./node()/*[2]/part/attribute::name)

  上面的这条查询将寻找根元素的第二个子元素,然后它将得到根元素的第二子元素的所有的part子元素。 接着它将寻找part子元素的name属性,最后它把name属性的值转换为一个字符串格式。 当把这条语句应用到代码段1中的时候,它将输出bill。

  XPath也提供一些布尔函数,返回"true/false",研究一下下面的这条查询:

  boolean(./node()/message)

  当把它应用到代码段1的时候,它返回true。 这是因为boolean()函数判断一个XPath查询产生的节点集是否为空(在我们的例子中,根元素包含两个message子元素)。 如果是空,boolean()函数返回false,否则返回true。


  一个复杂的WSDL处理实例

  下面的WSDL处理方案使用了我们前面讨论过的所有的XPath概念。 这个方案的检索要求如下:

  寻找一个service元素,这个元素是definitions元素(根元素)的一个直接子元素,并且name属性与definitions元素的name属性匹配。 然后察看service元素,寻找一个port元素,这个port元素的binding属性与definitions元素的直接子元素binding的name属性匹配。

  这个WSDL过程可以用四步完成:

  1. 查找definitions元素的name属性值。 下面给出的XPath查询(从代码段中返回字符串BillingService)执行这步操作:

  string(//node()[1]/@name)

  2. 然后查找name属性匹配definitions元素的name的service元素。 下面的查询将返回所需要的service元素:

  ./node()[1]/service[@name=string(//node()[1]/@name)]

  3. 然后查找binding元素的name属性值:

  string(//node()[1]/binding/@name)

  4. 最后寻找需要的port元素:

  ./node()[1]/service[@name=string(//node()[1]/@name)]

  /port[@binding=string(//node()[1]/binding/@name)]

  这个实例说明XPath谓词可以包含简单逻辑条件,函数调用乃至完整的XPath查询。

  使用XPath处理WML

  WML是WAP Forum定义的一种XML语言。 WML为小型设备的显示提供了一种表现格式。 WML对于一个小型设备就好像HTML对于一台个人电脑一样。

  想象一下,一个WML文件是由一组卡片(card)组成,每个卡片由一个card元素封装。 代码段3是一个简单WML文件,只包含两个card元素。

  下面的XPath查询将返回代码段3中包含在第一个卡片之内(这卡片id是" first")的所有的p(paragraph)元素:

  ./node()/card[string(@id)="first"]/p

  下面这个查询返回第二个卡片中的第一段的文本内容:

  string(./node()/card[string(@id)="second"]/p[1]/text())

  实现XPath谓词与函数

  我们现在将看看如何在我们前面的那个简单的XPath引擎中插入谓词与函数的支持。

  四个伪代码类XPathExpression(代码段4)、XPathLocationStep(代码段5)、XPathResult(代码段6)和Predicate(代码段7)组成了支持谓词与函数的更新的版本。 我们在上一篇文章介绍的XPath引擎的基础上,增加了下列功能,使之更加强大:

  1. XPath可以返回各种类型的数据。 XPath可以返回节点、字符串、数字和布尔变量。 我们设计的XPath引擎只支持XML节点作为返回数据类型。 我们现在已经提供了一个名为XPathResult(见代码段6)的类来支持不同的数据类型。 基于我们的设计的实现需要扩展为每种数据类型分别地扩展XPathResult。

  2. 更新的设计现在包括一个支撑函数的结构。 一个函数调用可以发生在一个XPath查询开始时,也可以发生在任何XPath location step。 因此,XPathExpression类(代码段4)和XPathLocationStep类(代码段5)现在都添加了对函数调用的支持。

  3. 我们还提供了一个单独的类用于支持谓词(见代码段7)。 一个谓词可以只由一个逻辑条件组成也可以由一个完整的XPath查询组成。 因此,Predicate类构造器将判断谓词到底是一个完整的查询还是仅仅只是一个条件。 如果是一个完整的XPath查询,Predicate表达式将实例化一个新的XPathExpression对象,否则它将只是取得逻辑条件的值。

  小结

  在前面,我们讨论XPath中谓词与函数的语法和使用。 我们介绍WSDL和WML处理的实例并说明了如何构成更加复杂的XPath查询。 最后,我们增强了在第一篇文章中介绍的XPath引擎的功能。


  代码段1:

<?XML version="1.0" encoding="UTF-8" ?>

<wsd:definitions name="BillingService"
targetNamespace="http://www.ElectricSupplyCompany.com/BillingService-interface"
XMLns:wsd="http://schemas.XMLsoap.org/wsdl/"
XMLns:soap="http://schemas.XMLsoap.org/wsdl/soap/"
XMLns:tns="http://www.ElectricSupplyCompany.com/BillingService"
XMLns:xsd="http://www.w3.org/1999/XMLSchema">

<message name="MonthNumber">
 <part name="number" type="xsd:int"/>
</message>

<message name="TotalBill">
 <part name="bill" type="xsd:int"/>
</message>

<portType name="BillingService_port">
 <operation name="getBillForMonth">
  <input message="MonthNumber"/>
  <output message="TotalBill"/>
 </operation>
 <operation name="getCurrentBill">
  <output message="TotalBill"/>
 </operation>
</portType>

<binding name="BillingService_Binding" type="BillingService_port">
<soap:binding style="rpc"
transport="http://schemas.XMLsoap.org/soap/http" />
 <operation name="getBillForMonth">
  <soap:operation soapAction="urn:BillingService" />
  <input>
   <soap:body
encodingStyle="http://schemas.XMLsoap.org/soap/encoding/" namespace="urn:BillingService"
use="encoded" />
  </input>
  <output>
   <soap:body
encodingStyle="http://schemas.XMLsoap.org/soap/encoding/" namespace="urn:BillingService"
use="encoded" />
  </output>
 </operation>

 <operation name="getCurrentBill">
  <soap:operation soapAction="urn:BillingService" />
  <input>
   <soap:body
encodingStyle="http://schemas.XMLsoap.org/soap/encoding/"
namespace="urn:BillingService"
use="encoded" />
  </input>
  <output>
   <soap:body
encodingStyle="http://schemas.XMLsoap.org/soap/encoding/"
namespace="urn:BillingService"
use="encoded" />
  </output>
 </operation>

</binding>

<service name="BillingService">
 <documentation> Billing Service of Electric Supply Company. </documentation>
 <port binding="BillingService_Binding" name="BillingService_ServicePort">
 <soap:address location="http://localhost:8080/soap/servlet/rpcrouter" />
 </port>
</service>

</wsd:definitions>

  代码段2:

<?XML version="1.0" encoding="UTF-8" ?>

<wsd:definitions name="BillingService"
targetNamespace="http://www.ElectricSupplyCompany.com/BillingService-interface"
XMLns:wsd="http://schemas.XMLsoap.org/wsdl/"
XMLns:soap="http://schemas.XMLsoap.org/wsdl/soap/"
XMLns:tns="http://www.ElectricSupplyCompany.com/BillingService"
XMLns:xsd="http://www.w3.org/1999/XMLSchema">

<message name="MonthNumber">
 <part name="number" type="xsd:int"/>
</message>

<message name="TotalBill">
 <part name="bill" type="xsd:int"/>
</message>

<message name="DetailedStatement">
 <part name="statement" type="xsd:string"/>
</message>

<portType name="BillingService_port">
 <operation name="getBillForMonth">
  <input message="MonthNumber"/>
  <output message="TotalBill"/>
 </operation>
 <operation name="getCurrentBill">
  <output message="TotalBill"/>
 </operation>
</portType>

<binding name="BillingService_Binding" type="BillingService_port">
<soap:binding style="rpc"
transport="http://schemas.XMLsoap.org/soap/http" />
 <operation name="getBillForMonth">
  <soap:operation soapAction="urn:BillingService" />
  <input>
   <soap:body
encodingStyle="http://schemas.XMLsoap.org/soap/encoding/" namespace="urn:BillingService"
use="encoded" />
  </input>
  <output>
   <soap:body
encodingStyle="http://schemas.XMLsoap.org/soap/encoding/" namespace="urn:BillingService"
use="encoded" />
  </output>
</operation>

<operation name="getCurrentBill">
 <soap:operation soapAction="urn:BillingService" />
 <input>
  <soap:body
encodingStyle="http://schemas.XMLsoap.org/soap/encoding/"
namespace="urn:BillingService"
use="encoded" />
 </input>
 <output>
  <soap:body
encodingStyle="http://schemas.XMLsoap.org/soap/encoding/"
namespace="urn:BillingService"
use="encoded" />
 </output>
</operation>

</binding>

<service name="BillingService">
<documentation> Billing Service of Electric Supply Company. </documentation>
<port binding="BillingService_Binding"
name="BillingService_ServicePort">
<soap:address
location="http://localhost:8080/soap/servlet/rpcrouter" />
</port>
</service>

</wsd:definitions>


  代码段3:

<?XML version="1.0" encoding="UTF-8" ?>
<wml>
 <!--简单的WML文件-->
 <card id="first">
  <p>
   First card.
  </p>
 </card>
 <card id="second">
  <p>
   First para of the Second card.
  </p>

  <p>
   Second para of the Second card.
  </p>

 </card>
 <!--可以在下面放入其它的card-->
</wml>

  代码段4:

public class XPathExpression
{
 DOM_Document XML_DOM;
 Array of Strings XPathLocationStepStringsArray;
 Array of XPathLocationSteps XPathLocationStepsArray;
 Array of XPathResults ResultNodeSet;

 XPathExpression (string XMLFile, string XPathExpression)
 {
  XML_DOM = XMLFile loaded into a DOM;
  FunctionName =
If there is any XPath function in the begining of the query,
store the function name here;
Strip the function name from the expression.

  XPathLocationStepStringsArray =
Tokenize XPath expression into smaller strings,
where each string is a location step.
Also unabbreviate any XPath abbreviations found;

  Integer locationStepCount = Number of location step strings
in XPathLocationStepStringsArray;
String IndividualXPathLocationStepString;
XPathLocationStep IndividualXPathLocationStep;

  ResultNodeSet = XML_DOM loaded into an array of XPathResults.

  Repeat locationStepCount times from i = 0 to locationStepCount-1:
  {
   IndividualXPathLocationStepString = XPathLocationStepStringsArray[i];
   IndividualXPathLocationStep = a new object of XPathLocationStep(
                  IndividualXPathLocationStepString,
                  XML_DOM
   );
   ResultNodeSet = IndividualXPathLocationStep.getResult(ResultNodeSet);
  }

  Apply the XPath function on the resulting node-set

 }

 XPathExpression (DOM_Document XML_DOM, string XPathExpression)
 {
  Same as the first constructor,
  except that it takes the XML file as a
  DOM object instead of a string.

 }

 public Array of XPathResults getResult()
 {
  return ResultNodeSet;
 }
}

  代码段5:

public class XPathLocationStep
{
 String Axis;
 String NodeTest;
 Array of XPathResults OutputNodeSet;
 String FunctionName;
 String Predicate;
 DOM_Document XML_DOM;

 XPathLocationStep(String XPathLocationStepString, DOM_Document XML_DOM_Document)
 {
  Resolve the XPathLocationStepString into FunctionName,
  Axis, NodeTest, and Predicate;
  XML_DOM = XML_DOM_Document;
 }

 Array of XPathResults getResult(Array of Nodes ContextNodeSet)
 {
  OutputNodeSet = new Array of XPathResults;

  Integer NodeCount =Number of nodes in ContextNodeSet;
  if (Axis is equal to "child" or "descendant")
  {
   Repeat NodeCount times for i = 0 to NodeCount-1
   {
    Node node = ContextNodeSet[i];
    Integer ChildCount = Number of node's children;
    Repeat ChildCount times for j = 0 to ChildCount-1
    {
     Node ChildNode =node.getChildElement(j);
     String ChldName =Name of the ChildNode;
     if (NodeTest is equal to ChildName)
      Add ChildNode to OutputNodeSet;
     if (Axis is equal to "descendant")
     {
      Array of Nodes Descendants =getMatchingDescendants(ChildNode);
      Add MatchingDescendants to OutputNodeSet;
     }
    }
   }
  }

  Predicate predicateEvaluator = new Predicate(OutputNodeSet, XML_DOM);
  OutputNodeSet = predicateEvaluator.getResult();
  return OutputNodeSet;

 }

 private Array of Nodes getMatchingDescendants(Node node)
 {
  Array of Nodes MatchingDescendants;
  Integer ChildCount = Number of node's children;
  Repeat NodeCount times for j = 0 to ChildCount-1
  {
   Node ChildNode =node.getChildElement(j);
   String ChildName =Name of the ChildNode;
   if (NodeTest is equal to ChildName)
    Add ChildNode to MatchingDescendants;

   Array of Nodes MoreDescendants =getMatchingDescendants(ChildNode);
   Add MoreDescendants to MatchingDescendnts;
  }
  return MatchingDescendants;
 }

}

  代码段6:

public class XPathResult
{ string ResultType = "ArrayOfNodes";

 string getResultType
 {
  return ResultType;

 }

 public setResultType (string Type)
 {
  ResultType = Type;
 }
}

  代码段7:

public class Predicate
{
 Array of XPathResults ResultSet;

 Predicate(Array of XPathResults ResultSet,
 DOM_Document XML_DOM)
 {
  Check if this predicate is just a logical condition or a complete XPath query.
  If it is a complete XPath expression
  {
   ResultSet = (new XPathExpression(XML_DOM, XPath Expression))
   .getResult();
  }
  else
  {
   ResultSet = Filtered result set;
  }
 
 }

 Array of XPathResults getResult()
 {
  return ResultSet;
 }

}


在百度中搜索:XPath在无线应用中的实现(下)
在Google中搜索:XPath在无线应用中的实现(下)
在Yahoo中搜索:XPath在无线应用中的实现(下)

收藏到网摘:新浪VIVI 365key 我摘 POCO网摘 博采中心 YouNote 和讯网摘 天天收藏
[] [返回上一页] [打 印] [收 藏]
下一篇文章:初探PHP5

 相关文章    最新文章
· 怎样做XP和Vista双系统
· 让Windows XP不再出现内存读写错误
· Windows XP手动安装IPv6协议的方法
· 微软否认“挽救XP电话请愿”计划
· [图文] 安装Windows XP SP3后系统蓝屏的解..
· 自建批处理设定Win XP启动项目顺序
· 20多万用户要求延长XP寿命 微软置之不理
· XP销售大限将至 Vista终盼到出头之日
· 两个命令强化XP系统磁盘清理工具
· 卸载诺顿之后WinXP丢失IP无法上网
 
· XML和XSLT结合进行网站设计
· 网页教程:XML技巧五则
· XML语法概述
· XML轻松学习手册
· XML 中的常见问题(3)
· XML 中的常见问题(2)
· XML 中的常见问题(1)
· 用XSLT生成网页菜单(2)
· 用XSLT生成网页菜单(1)
· 将改变我们生活的这些XML应用之二

∷相关文章评论∷    (评论内容只代表网友观点,与本站立场无关!) [更多评论…]
站内搜索

精彩图文
  网站导航  
操作系统 办公软件 网络软件
Vista Windows2003 WindowsXP Windows2000/NT Windows9X/ME Linux 其他 Word Excel Powerpoint Outlook 金山系列 其他 网页浏览 上传下载 联络聊天 邮件工具 服务器软件 网络辅助
工具软件 媒体动画 网页制作
系统工具 媒体工具 压缩工具 图文处理 文件管理 其他 3DMAX Authorware Director Maya 视频处理 其他 Flash Dreamweaver FireWorks FrontPage LiveMotion Golive HTML/CSS 其它
网站开发 平面设计 程序设计
ASP JSP PHP CGI JavaScript VBScript XML/SOAP Web服务器 Photoshop PhotoImpact CorelDraw Illustrator Freehand 设计欣赏 其他 VB VC .NET C/C++ DELPHI JAVA

冀ICP备05019428号
Copyright © 2004-2008 电脑学习网 Inc.All rights reserved.
TEL:13832340607
QQ:39873155
E_Mail:goodsgy(#)hotmail.com   (把(#)替换成@)
MSN:goodsgy(#)hotmail.com   (把(#)替换成@)