XP1*_*XP1 22 xml d xml-parsing
如何从头创建/编写一个简单的XML解析器?
我想知道英语中简化的基本步骤,而不是代码示例.
一个好的解析器是如何设计的?我知道正则表达式不应该在解析器中使用,但正则表达式在解析XML中的作用是多少?
建议的数据结构是什么?我应该使用链表来存储和检索节点,属性和值吗?
我想学习如何创建XML解析器,以便我可以用D编程语言编写一个.
Mic*_*Kay 11
如果您不知道如何编写解析器,那么您需要进行一些阅读.掌握任何关于编译器编写的书(许多最好的书是在30或40年前编写的,例如Aho和Ullmann)并研究词汇分析和语法分析的章节.XML基本上没有什么不同,除了词法和语法阶段不像某些语言那样彼此明显隔离.
一句警告,如果你想编写一个完全符合要求的XML解析器,那么90%的努力将用于在规范的模糊角落中处理边缘情况,例如大多数XML用户甚至不参与的参数实体意识到.
解析器和节点列表之间存在差异.解析器是一个部分,它接受一堆纯文本XML并尝试确定那里有哪些节点.然后是一个保存节点的内部结构.在该结构的一个层中,您可以找到DOM,即文档对象模型.这是构成XML文档的嵌套节点的结构.解析器只需知道通用DOM接口即可创建节点.
我不会使用正则表达式作为解析器.我认为最好的事情只是通过char遍历字符串char并检查你得到的是否与你应该得到的匹配.
但为什么不使用任何现有的XML解析器呢?编码数据有很多种可能性.很多例外.如果您的解析器不管理它们,则几乎不值得使用XML解析器的标题.
并基于事件的解析器,用户需要通过它的一些功能(startNode(name,attrs),endNode(name)并someText(txt)有可能通过一个接口),并呼吁他们在需要的时候为你传过来的文件
解析器将有一个while循环,它将在读取之前<和之后交替>,并对参数类型进行适当的转换
void parse(EventParser p, File file){
string str;
while((str = file.readln('<')).length !=0){
//not using a rewritable buffer to take advantage of slicing
//but it's a quick conversion to a implementation with a rewritable buffer though
if(str.length>1)p.someText(str.chomp('<'));
str = file.readln('>');
str = str.chomp('>');
//split str in name and attrs
auto parts = str.split();
string name = parts[0];
string[string] attrs;
foreach(attribute;parts[1..$]){
auto splitAtrr = attribute.split("=");
attrs[splitAtrr[0]] = splitAtrr[1];
}
if(str[0] == '/')p.endNode(name);
else {
p.startNode(name,attrs);
if(str[str.length-1]=='/')p.endNode(name);//self closing tag
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在基于事件的解析器之上构建DOM解析器,并且每个节点所需的基本功能是getChildren和getParent getName和getAttributes(在构建时使用setter;))
使用上述方法的dom解析器的对象:
class DOMEventParser : EventParser{
DOMNode current = new RootNode();
overrides void startNode(string name,string[string] attrs){
DOMNode tmp = new ElementNode(current,name,attrs);
current.appendChild(tmp);
current = tmp;
}
overrides void endNode(string name){
asser(name == current.name);
current = current.parent;
}
overrides void someText(string txt){
current.appendChild(new TextNode(txt));
}
}
Run Code Online (Sandbox Code Playgroud)
当解析结束时,rootnode将具有DOM树的根
注意:我没有在其中放置任何验证码以确保xml的正确性
编辑:属性的解析有一个错误,而不是在空格上拆分正则表达式更好