转换自定义类XML语法的最佳方法

2024-04-24 15:27:37 发布

您现在位置:Python中文网/ 问答频道 /正文

使用Python。在

所以基本上我有一个类似XML的标记语法,但是标记没有属性。所以<a>而不是{}。它们有规律地以</a>结束。在

这是我的问题。我有些东西看起来像这样:

<al>
1. test
2. test2
 test with new line
3.  test3
<al>
    1. test 4
    <al>
        2. test 5
        3. test 6
        4. test 7
    </al>
</al>
4. test 8
</al>

我想把它变成:

^{pr2}$

我不是在寻找一个完整的解决方案,而是朝着正确的方向努力。我只是想知道这里的人会如何处理这个问题。仅仅是正则表达式?为无属性标记语法编写一个完整的自定义解析器?破解现有的XML解析器?等等

提前谢谢


Tags: 标记test解析器new属性withline语法
3条回答

我建议从以下几点开始:

from xml.dom.minidom import parse, parseString

xml = parse(...)
l = xml.getElementsByTagName('al')

然后遍历l中的所有元素,检查它们的文本子节点(以及<al>节点递归)。在

您可以立即在Python控制台中使用它。在

很容易移除文本节点,然后使用chunk.split('\n')拆分文本块,并根据需要添加<li>节点。在

修改完所有的<al>节点后,您只需调用xml.toxml()以获得文本形式的xml。在

请注意,从中获取的元素对象链接回原始的xml文档对象,因此不要在进程中删除{}对象。在

我个人认为这种方式比使用多行regexp更直接、更容易调试。在

I am just wondering how the folks here would approach the problem.

我会选择使用解析器。

我的理由是,你试图执行的操作不仅仅是一个句法或词汇替换。它更像是一个语法转换,这意味着理解文档的结构。在

在您的示例中,您并不是简单地将<li></li>之间的每一行都括起来;您还递归地封闭跨越多行的文档块,如果这些块表示一个“项”。在

也许你可以把一个regex放在一起,它能够捕获问题的解释逻辑和递归性质,但是这样做就像用茶匙挖沟:你可以这样做,但是使用spade(解析器)是一个更符合逻辑的选择。在

使用解析器的另一个原因是“实词”。Regex是真正的“语法纳粹”:你的标记出现故障,它们就不能工作了。另一方面,所有的解析器库都是“灵活的”(统一处理不同的拼写,比如<a></a>和{}或HTML的<br>和XHTML的{}),而一些类似beautifulsoup甚至是“宽容的”,这意味着它们将尝试(以惊人的高精度)猜测文档作者想要编写的代码,即使文档本身未通过验证。在

而且,基于解析器的解决方案比基于regex的解决方案更易于维护。文档结构中的一个小变化可能需要对正则表达式进行彻底的更改[这在72小时左右之后,对于自己的作者来说,这很容易变得模糊]。在

最后,由于您使用的是python和thereforereadability counts,基于解析器的解决方案可能会产生比非常复杂/冗长/晦涩的regex更多的python代码。在

啊!在

您描述语法的方式是“没有属性的XML”。如果是这样的话,它仍然是XML,所以可以使用XSLT和XQuery等XML工具。在

另一方面,如果允许XML中不允许的东西,那么我的方法是编写一个解析器来处理您的非XML格式并提供与XML兼容的SAX事件。然后您就可以使用任何XML技术,只需插入解析器来代替常规的XML解析器。在

相关问题 更多 >