网页编程必看:XML文法分析
在进行XML文法分析之前,首先有必要了解XML语法的基本规则: 词法特征:1)XML区分大小写,如元素名在打开和关闭标记中应保持大小写一致<mytag>…</mytag>,XML的保留词串应符合大小写要求<?xml …> <!ENTITY>…。 2)XML保留标记字符为:< > &,保留字符不允许出现在元素名、元素文本、属性名、属性值中,< 用户打开标记,>用于关闭标记,&用于转意,常见的转意为 <生成<,>生成>,&生成&,&apos生成’,"生成” 3)元素名以下划线或字母开始,可包含字母、数字、句点、连字符、下划线、冒号和用于其他语言的扩展字符,元素名中不能有空格符(分格符、跳格符、换行符、回车符),元素名可以由名域前缀。如:<mytag> <dt:mytag> 元素文本可以是除XML保留字符外的字符集合,如<mytag> my money is $2000 </mytag> 4)属性名的规则同元素名,属性值由单引号或双引号括约其中,可由除XML保留字符以外的字符串组成,如:<mytag myprop=”proper value”>。属性名有xmlns前缀,表明该属性定义了一个名域,如:<mytag xmlns:ns=”http://www.myweb.com/myschema”> 句法特征:1)XML文档由一个XML说明、多个可选的文档说明、多个可选的XML指令、多个可选的XML注释和一个根元素的数据体组成,此外还可以有嵌入语句中的CDATA段,如:
2)XML说明由<?xml打开,由?>标关闭,其中包含版本、编码等可选说明,如:<?xml version=”1.0” encoding=”UTF-9”?> 3)XML文档说明由<!和保留串打开,由>关闭,如:<!DOCTYPE mydoc SYSTEM “mydoc.dtd”> 4)XML指令由<?和保留串打开,由?>关闭,如:<?xml-stylesheet type=”text/xsl” href=”mystyle.xsl”?> 5)XML注释由<! 打开,由 >关闭,如:<!-- this is my xml document --> 6)XML元素由<元素名>打开,由/>,或</元素名>关闭,元素的打开和关闭标记相互匹配,如<myteg ../>或<mytag>…</myteg>,XML的元素允许嵌套,应此还应保持层次上的匹配,如<myteg><subtag>..</subtag></mytag>。 7)CDTATA段由<![CDATA[>打开,由]]>关闭,用于使居于其中的语句规避XML解析规则。如:<![CDATA[ select * from mytable where thefield <= ‘100’ ]]> 根据以上的XML文法特征,可以构造出用于词法分析的正则式和用于句法分析的下推自动机结构。 XML词法正则式: #define digit [1,2,…,9] /*数字字符*/ #define letter [a,b,…,z,A,B,…,Z] /*字母字符*/ #define signs [~, ! , @, #, %, ^, &,*,(, ), ?, :, ;, “, ‘, ,, ., /,-, _, +, =, |, /] /*符号字符*/ #define ascii2 [0x80,…,0xFF] /*ASCII chart2 扩展字符*/ #define space [0x20, /t, /r, /n] /*空格符,跳格符,回车符,换行符*/ #define reserve [< , >, &] /*XML保留字符*/ 1) 元素名的正则式: element_name -> (_ | letter | ascii2) (ε| _ | - | : | . | digit | letter | signs | ascii2)* 2) 元素文本的正则式: element_text -> (ε| not reserve)* 3) 属性名的正则式: proper_name -> (_ | letter | ascii2) (ε| _ | - | : | . | digit | letter | signs | ascii2)* 4) 属性文本的正则式: proper_value -> (ε| not reserve)* XML句法结构: xml_document -> xml_header (ε| xml_declare | xml_instruct | xml_comments)* xml_element xml_header -> [<?xml](space)*(proper_token)*(space)* [?>] xml_declare -> [<!]reserve_word(space)*(token)*(space)*[>] xml_instruct -> [<?]reserve_word(space)* (proper_token)* (space)*[?>] xml_comments -> [<!--](ε| digit | letter | signs | ascii2 | space)*[-- >] xml_element -> [<]element_name (space)*( ε| proper_token)*(space)*[/>] | [<]element_name(space)*( ε | proper_token)*(space)*[>] [ε| <![CDATA[ ]element_text[ε| ]]>] (ε | xml_element)*(space)*[</]element_name[>] proper_token -> proper_name(space)*[=](space)* [ε| <![CDATA[ ] [‘ | “]proper_value[‘ | “] [ε| ]]>] reserve_word -> [DOCTYPE | ELEMENT | NOTATION | …] token -> (ε| not reserve)* 分析XML文法需要构造一个下推自动机,它的结构定义如下: 1)STACK_DFA mata_xml_doc = <Q,Σ,σ,q,Γ,T,S >
4)栈顶动作:PUSH: 将当前节点和状态压入栈
namepre (NOP,IS_NAME_BEGIN,PAUSE) /*指令名开始*/ (NS_KEY_BEGIN) space (NOP,NS_NAME_END,PAUSE) /*属性名结束*/ = (NOP,NS_KEY_END,PAUSE) /*属性赋值符*/ & (NOP,NS_KEY_BEGIN,SKIP) /*字符转义*/ name (NOP,NS_KEY_BEGIN,NEXT) /*继续属性名*/ other (NOP,NIL_FAILED,STOP) /*非法字符*/ (NS_KEY_END) space (NOP,NS_KEY_END,NEXT) /*忽略空格*/ = (NOP,NS_ASIGN,NEXT) /*属性赋值符*/ other (NOP,NIL_FAILED,STOP) /*非法字符*/ (NS_ASIGN) space (NOP,NS_ASIGN,NEXT) /*忽略空格*/ “ (NOP,NS_VAL_BEGIN,NEXT) /*属性赋值打开*/ ‘ (NOP,NS_VAL_BEGIN,NEXT) /*属性赋值打开*/ other (NOP,NIL_FAILED,STOP) /*非法字符*/ (NS_VAL_BEGIN) “ (NOP,NS_VAL_END,NEXT) /*属性值结束*/ ‘ (NOP,NS_VAL_END,NEXT) /*属性值结束*/ & (NOP,NS_VAL_BEGIN,SKIP) /*字符转义*/ token (NOP,NS_VAL_BEGIN,NEXT) /*继续属性值*/ other (NOP,NIL_FAILED,STOP) /*非法字符*/ (NS_VAL_END) space (NOP,NS_VAL_END,NEXT) /*忽略空格*/ > (NOP,TG_INT_CLOSE,NEXT) /*标记中断*/ other (NOP,NS_KEY_BEGIN,PAUSE) /*属性名开始*/ (TG_INT_CLOSE) < (PUSH,TG_OPEN,NEXT) /*标记开始*/ other (NOP,NS_TEXT_BEGIN,PAUSE) /*元素文本开始*/ (NS_TEXT_BEGIN) < (NOP,NS_TEXT_END,PAUSE) /*元素文本结束*/ & (NOP,NS_TEXT_BEGIN_BEGIN,SKIP) /*字符转义*/ token (NOP,NS_TEXT_BEGIN,NEXT) /*继续元素文本*/ other (NOP,NIL_FAILED,STOP) /*非法字符*/ (NS_TEXT_END) < (PUSH,TG_OPEN,NEXT) /*标记开始*/ other (NOP,NIL_FAILED,STOP) /*非法字符*/ (TG_PRE_CLOSE) > (NOP,TG_CLOSE,PAUSE)/*标记结束*/ name (NOP,TG_PRE_CLOSE,NEXT) /*继续关闭标记的元素名*/ other (NOP,NIL_FAILED,STOP) /*无效字符*/ (TG_CLOSE) > (POP,NEXT) /*标记关闭,出栈*/ other (NOP,NIL_FAILED,STOP) /*非法字符*/ 对XML声明,本文只做了忽略处理,可以通过增加XML声明的状态和状态转移列表,进而支持XML声明的分析。 |
- 上一篇:XML 中的常见问题 (一)
- 下一篇:XML的四种解析器原理及性能比较