首页 | 互联网 | IT动态 | IT培训 | Cisco | Windows | Linux | Java | .Net | Oracle | 软件测试 | C/C++ | 嵌入式开发 | 存储世界 | 服务器
网络设备 | IDC | 安全 | 求职招聘 | 数字网校 | 网页设计 | 平面设计 | 技术专题 | 电子书下载 | 教学视频 | 源码下载 | 搜索 | 博客 | 论坛
中国IT实验室Dotnet频道
中国IT教育
Google
首页 ASP.NET  C#  XML/WebService ADO.NET VC.NET VB.NET .NET 资讯动态 专题 RSS订阅 讨论 下载
您现在的位置: 中国IT实验室 >> Dotnet >> XMLWeb >> 正文

PHP中的XML拉模式详细解析

  当然,并非所有节点类型都具有所有这些属性。例如,文本节点、CDATA 部件、注释、处理指令、属性、空格、文档类型和 XML 声明具有值。而其它节点类型(最重要的是元素和文档)则没有值。通常,程序将使用 nodeType 属性来断定它所查找的内容,然后做出适当的响应。清单 3 展示了简单的 while 循环,该循环使用这些函数来打印它所查看的内容。清单 4 展示了将清单 1 输入程序后的输出。

  清单 3. 解析器所查看的内容

以下是引用片段:
  while ($reader->read()) {
  echo $reader->name;
  if ($reader->hasValue) {
  echo ": " . $reader->value;
  }
  echo "\n";
  }

  清单 4. 清单 3 的输出

以下是引用片段:
  methodCall
  #text:
  methodName
  #text: sqrt
  methodName
  #text:
  params
  #text:
  param
  #text:
  value
  double
  #text: 10
  double
  value
  #text:
  param
  #text:
  params
  #text:
  methodCall

  大多数程序并非这么简单。它们接受特定格式的输入,并以某种方式来处理输入。在 XML-RPC 例子中,仅需要读取输入中的一个元素:double 元素,该元素应该只有一个。为此,查找名称为 double 的元素的起点:

以下是引用片段:
  if ($reader->name == "double"
  && $reader->nodeType == XMLReader::ELEMENT) {
  // ...
  }

  该元素可能有单个文本子节点,可以通过将解析器前进到下一个节点来进行读取,如下所示:

以下是引用片段:
  if ($reader->name == "double" && $reader->nodeType == XMLReader::ELEMENT)
 {
  $reader->read();
  respond($reader->value);
  }

  在这里 respond() 函数构建了 XML-RPC 响应并将它发送到客户机。但是,在展示上述操作前,还有一些事情需要处理。不能绝对保证请求文档中的 double 元素仅包含一个文本节点。可能包含多个文本节点,以及注释和处理指令。例如,可能看起来像以下代码:

以下是引用片段:
<value><double>
  <!--value follows-->6.<!--fractional part next-->0
</double></value>

  嵌套元素

  该模式存在一个潜在的缺陷。嵌套的 double 元素(例如 61.2)将违背该算法。然而它将成为无效的 XML-RPC;并且不久您将看到如何使用 RELAX NG 验证来拒绝所有此类文档。在诸如可扩展超文本标记语言(Extensible Hypertext Markup Language,XHTML)之类的文档类型中,允许相同元素互相包含(例如 table 元素包含在另一个 table 元素中),因此您还需要知道元素的深度,从而确保结束标记与开始标记之间进行正确匹配。

  一个健壮的解决方案需要获得 double 元素的所有文本子节点,将它们连接起来,并且仅将结果转换为 double.必须小心避免任何注释或可能出现的其它非文本节点。这有一点复杂,但并不是十分复杂,如清单 5 所示。

  清单 5. 累积来自一个元素的所有文本内容

以下是引用片段:
  while ($reader->read()) {
  if ($reader->nodeType == XMLReader::TEXT
  || $reader->nodeType == XMLReader::CDATA
  || $reader->nodeType == XMLReader::WHITESPACE
  || $reader->nodeType == XMLReader::SIGNIFICANT_WHITESPACE) {
  $input .= $reader->value;
  }
  else if ($reader->nodeType == XMLReader::END_ELEMENT
  && $reader->name == "double") {
  break;
  }
  }

  您可以暂时忽略文档中的其它任何内容。(稍后将添加更多的错误处理。)

  构建响应

  正如它的名称所暗示的,XMLReader 仅仅用于读取。相应的 XMLWriter 类正在开发中,但还不能投入到生产。幸运的是,写入 XML 比读取 XML 要容易得多。首先,应使用 header() 函数来设置响应的媒体类型。对于 XML-RPC 来说,媒体类型是 application/xml.例如:

以下是引用片段:
header('Content-type: application/xml');

  通常直接将内容显示在页面上,如清单 6 中的 respond() 函数所示。

  清单 6. Echo XML

以下是引用片段:
  function respond($input) {
  echo "
  " .
  sqrt($input)
  . "
  ";
  }

  甚至可以将响应的文字部分直接嵌入 PHP 页面中,就像使用 HTML 时一样。清单 7 展示了该技术。

  清单 7. 文字表示的 XML

以下是引用片段:
  function respond($input) {
  ?>
  "
  echo sqrt($input);
  ?>
  }

  错误处理

  到现在为止,一直隐含假定输入文档是格式规范的文档。但是不能保证情况都是如此。像任何 XML 解析器一样,只要发现一个规范格式错误,XMLReader 就必须停止处理。如果是这样的话,read() 函数将返回 false.

  从理论上讲,解析器将报告数据直到发现第一个错误。但是在对小型文档进行试验时,几乎是立刻显示错误信息。底层解析器将预解析大块文档,对它进行缓存,然后每次分发出一小块文档。因此往往会过早地检查错误。出于安全考虑,不要假定在发现第一个规范格式错误之前能够解析内容。此外,也不要假设解析错误出现之前看不到任何内容。如果希望只接受完整的、格式规范的文档,那么请确保在看到文档终点之前脚本不能进行任何不可逆操作。

  如果解析器检测到规范格式错误,那么 read() 函数将显示如下错误消息(如果启用了详细错误报告,且位于开发服务器上时):

以下是引用片段:
  Warning: XMLReader::read() [function.read]:
  < value>10 in /var/www/root.php
  on line 35

  您可能不希望将它复制到用户所看到的 HTML 页面中。更好的方法是在 $php_errormsg 环境变量中捕获错误消息。为此,需要启用 php.ini 文件中的 track_errors 配置选项:

以下是引用片段:
track_errors = On

  默认情况下,track_errors 选项是关闭的;这在 php.ini 中是显式指定的,因此请确保更改了该行代码。如果提早在 php.ini 中添加了上述一行代码(正如最初我所进行的操作),则后面的 track_errors = Off 代码将重写先前的代码。

上一页  [1] [2] [3] 下一页

【责编:John】

中国IT教育

相关产品和培训
文章评论
 友情推荐链接
 认证培训
 社区讨论
 博客论点
 Dotnet频道相关导航