繁体   English   中英

xml DTD文件的解析器

[英]Parser for xml DTD file

我在实现解析器方面很新,我正在尝试解析xml DTD文件以为其生成上下文无关的语法。 我尝试了pyparsing和yacc,但仍然可以获得任何结果。 因此,如果有人可以为我提供一些技巧或示例代码来编写这样的解析器,我将不胜感激。 以下是示例DTD文件:

<!DOCTYPE PcSpecs [
<!ELEMENT PCS (PC*)>
<!ELEMENT PC (MODEL, PRICE, PROCESSOR, RAM, DISK+)>
<!ELEMENT MODEL (\#PCDATA)>
<!ELEMENT PRICE (\#PCDATA)>
<!ELEMENT PROCESSOR (MANF, MODEL, SPEED)>
<!ELEMENT MANF (\#PCDATA)>
<!ELEMENT MODEL (\#PCDATA)>
<!ELEMENT SPEED (\#PCDATA)>
<!ELEMENT RAM (\#PCDATA)>
<!ELEMENT DISK (HARDDISK | CD | DVD)>
<!ELEMENT HARDDISK (MANF, MODEL, SIZE)>
<!ELEMENT SIZE (\#PCDATA)>
<!ELEMENT CD (SPEED)>
<!ELEMENT DVD (SPEED)>
]>

提前致谢。

这是您的起点,它将数据解析为ParseResults数据结构,然后您可以遍历并为定义的doctype创建解析器:

from pyparsing import *

LT,GT,EXCLAM,LBRACK,RBRACK,LPAR,RPAR = map(Suppress,"<>![]()")
DOCTYPE = Keyword("DOCTYPE").suppress()
ELEMENT = Keyword("ELEMENT").suppress()
ident = Word(alphas, alphanums+"_")
elementRef = Group(ident("name") + Optional(oneOf("* +")("rep")))
elementExpr = infixNotation(elementRef,
    [
    (',', 2, opAssoc.LEFT),
    ('|', 2, opAssoc.LEFT),
    ])
PCDATA = Literal(r"\#PCDATA")
elementDefn = Group(LT+EXCLAM + ELEMENT + ident("name") + 
                  LPAR + (elementExpr | PCDATA("PCDATA"))("contents") + RPAR + GT)
doctypeDefn = LT+EXCLAM + DOCTYPE + ident("name") + 
                    LBRACK + ZeroOrMore(elementDefn)("elements") + RBRACK + GT

我开始只是对每个ELEMENT定义中的元素列表使用delimitedList,但是随后我注意到了','和'|' 实际上是运算符,而不仅是定界符,甚至可以混合使用,例如“ A,B,C | D,E”。 因此,我使用pyparsing的infixNotation助手来允许这些定义。

使用您的输入样本,我可以解析并显示结果:

doctype = doctypeDefn.parseString(sample)
print doctype.dump()
for elem in doctype.elements:
    print elem.dump()

赠送:

['PcSpecs', ['PCS', ['PC', '*']], ['PC', [['MODEL'], ...
- elements: [['PCS', ['PC', '*']], ['PC', [['MODEL'], ...
- name: PcSpecs
['PCS', ['PC', '*']]
- contents: ['PC', '*']
  - name: PC
  - rep: *
- name: PCS
['PC', [['MODEL'], ',', ['PRICE'], ',', ['PROCESSOR'], ',', ['RAM'], ',', ['DISK', '+']]]
- contents: [['MODEL'], ',', ['PRICE'], ',', ['PROCESSOR'], ',', ['RAM'], ',', ['DISK', '+']]
- name: PC
['MODEL', '\\#PCDATA']
- PCDATA: \#PCDATA
- contents: \#PCDATA
- name: MODEL
['PRICE', '\\#PCDATA']
- PCDATA: \#PCDATA
- contents: \#PCDATA
- name: PRICE
['PROCESSOR', [['MANF'], ',', ['MODEL'], ',', ['SPEED']]]
- contents: [['MANF'], ',', ['MODEL'], ',', ['SPEED']]
- name: PROCESSOR
['MANF', '\\#PCDATA']
- PCDATA: \#PCDATA
- contents: \#PCDATA
- name: MANF
['MODEL', '\\#PCDATA']
- PCDATA: \#PCDATA
- contents: \#PCDATA
- name: MODEL
['SPEED', '\\#PCDATA']
- PCDATA: \#PCDATA
- contents: \#PCDATA
- name: SPEED
['RAM', '\\#PCDATA']
- PCDATA: \#PCDATA
- contents: \#PCDATA
- name: RAM
['DISK', [['HARDDISK'], '|', ['CD'], '|', ['DVD']]]
- contents: [['HARDDISK'], '|', ['CD'], '|', ['DVD']]
- name: DISK
['HARDDISK', [['MANF'], ',', ['MODEL'], ',', ['SIZE']]]
- contents: [['MANF'], ',', ['MODEL'], ',', ['SIZE']]
- name: HARDDISK
['SIZE', '\\#PCDATA']
- PCDATA: \#PCDATA
- contents: \#PCDATA
- name: SIZE
['CD', ['SPEED']]
- contents: ['SPEED']
  - name: SPEED
- name: CD
['DVD', ['SPEED']]
- contents: ['SPEED']
  - name: SPEED
- name: DVD

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM