Categories: PHP | Tags: | Views: 4,101

 

没错, 有人说, 你这不是纯粹吃饱了撑着吗?

是的, xml作为数据载体拥有众多优势, 使得其应用越来越广泛.

越来越多的语言也自带了很多xml解析库.

但是到底是如何解析那一堆xml字符串的, 少有人探究.

我也无从得知, 久前也尝试自己解析过, 但是方法很笨拙.

前两天从盒子里放着的小盒子, 我想到了稍好一些的解析方法.

-> 理解xml的结构

  每一个xml的标签比较是闭合的, 可以嵌套, 但不可以交叉.比如这样的结构是可以的:  

<root>
    <a>
        <b>test</b>
    </a>
</root>

 

  但是这样是不被允许的:

 

<root>
<a></b>
<b></a>
</root>

 

  每一个xml文件只能有一个根.

  每个标签可以有自己的属性, 这个和HTML类似

  标签的值被其开始标签和结束标签所包围

  如果值比较复杂,或者其中含有打乱xml结构的字符, 可以采用cdata

  如果标签没有值, 可以采用这种方式简写:

 

<tag />

 

-> 精妙的比喻

  这个比喻是从那两个盒子想到的.

  每个盒子必须有盖子(标签闭合)

  小盒子可以放在大盒子里(标签可以嵌套)

  每个盒子的盖子必须盖在自己的盒身上(不能交叉)

  现在有一堆盒子, 我们要把它们按照指定的关系(谁放在谁里面, 谁放在谁外面)整理好, 放在一个大盒子(那个唯一的根)里拎走.

  我们考虑的, 就是这个放置的过程.

  可以很直观的发现:   先放的盒子后盖盖, 后放的盒子先盖盖, 如果里面不用放盒子了, 直接盖上盖.

  (-为什么? -什么, 你问我为什么? 那..那…我问谁去?! 呃, 如果你有这个疑问, 建议你不要往下看了)

  (-哇! -嘘! 现在是偶在说话, 就算你发现了秘密, 也要等偶说完嘛. 如果你发出了这样的惊叹, 请继续往下看)

  看到这里, 相信你已经能够把这个过程和xml的解析联系起来了吧.

  如果我们把这个整理例子的过程看成是我们还读/写整个xml文件的过程, 那么就是这样:

  先读到的标签, 一定是比后读到的标签后闭合.

->如何解析?

  好了,  早就有人不耐烦了, 终于到正题了, 说了半天, 你还是没说怎么解析嘛.

  先读到的后闭合, 先读到的后闭合……

  我想到了, 你想到了么? 是什么? 堆栈!! 没错, 就是堆栈!

  容易了吧, 容易了吧, 简单了吧, 简单了吧…

  读xml的字符串, 每读到一个开始标签, 压入堆栈, 每读到一个闭合标签, 弹出栈顶元素, 那么, 现在的栈顶元素就是它的直接父节点.

  (-为什么,为什么,为什么? -哪来那么多为什么?! 盖上盖子, 先于这个盒子放进去, 且没有盖盖子的盒子, 是不是它的父盒子? 是不是, 是不是?

  注意这里没有盖盖子很重要, 因为盖上了盖子就不能往里放盒子了, 也没不可能有这个子盒子了, 因为盖上盖子就弹出堆栈了.)

  元素得到了, 它的父节点也得到了(相当于得到了子节点(父节点的子节点)), 那么所有的元素都串起来了, 解析也就简单了.

 

 

RELATED POSTS:

  1. php的mysql数据库操作类
  1. September 4th, 2010 at 11:07
    Reply | Quote | #1

    还是图片明了啊。。那个盒子的举例差点绕进去了。。 :)
    不知道具体代码你有没写出来~学习一下,虽然原理清楚了。。。
    ———-
    PS:你的验证码输入在chrome看不到啊。。

    • September 6th, 2010 at 09:06
      Quote | #2

      @fatkun: 代码写出来了,还需要整理一下.
      PS:你是指的算术验证码?

  2. September 21st, 2010 at 13:27
    Reply | Quote | #3

    O(∩_∩)O~不错,自己试试才是最好的!

  3. 17wz8.com
    October 11th, 2010 at 13:20
    Reply | Quote | #4

    自己编写很麻烦,反正有软件或者插件,所以很少了这个

  4. November 25th, 2010 at 18:00
    Reply | Quote | #5

      和谐使宇宙运转不停。

  5. November 27th, 2010 at 23:13
    Reply | Quote | #6

    博主还是很厉害的呀!!

;) :| :x :twisted: :roll: :oops: :o :mrgreen: :lol: :idea: :evil: :cry: :arrow: :P :D :?: :? :) :( :!: 8O 8)

你可以使用@somebody:开头, 来邮件通知somebody你回复了他的留言(用户名区分大小写).