如何在Python中使用简化的RELAX NG架构验证XML文档?

9 投票
3 回答
5203 浏览
提问于 2025-04-15 13:30

我该如何在Python中通过紧凑的RELAX NG模式来验证XML文档呢?

3 个回答

0

除了使用jingtrang或其他外部工具之外,还有一个选择,就是使用一个叫做 rnc2rng 的Python库。这个库可以加载RNC格式的文件,并把它转换成ReleaxNG的XML格式字符串,然后可以把这个字符串加载到lxml的RelaxNG类中。

想了解更多细节,可以查看 这个问题

2

如果你想在命令行中检查语法和Compact RelaxNG语法,可以使用pyjing,这个工具来自jingtrang模块。

它支持.rnc文件,并且提供的信息比单纯的TrueFalse要多。例如:

C:\>pyjing -c root.rnc invalid.xml
C:\invalid.xml:9:9: error: element "name" not allowed here; expected the element end-tag or element "bounds"

注意:这是一个Python的封装工具,底层使用的是Java的jingtrang,所以你需要先安装Java。

如果你想在Python中检查语法,可以按照以下步骤操作:

  1. 使用pytrang(来自jingtrang的封装)将“Compact RelaxNG”格式的文件(.rnc)转换为XML RelaxNG格式(.rng): pytrang root.rnc root.rng

  2. 使用lxml来解析转换后的.rng文件,具体可以参考这个链接:https://lxml.de/validation.html#relaxng

大致的操作会是这样的:

>>> from lxml import etree
>>> from subprocess import call

>>> call("pytrang root.rnc root.rng")

>>> with open("root.rng") as f:
...    relaxng_doc = etree.parse(f)
>>> relaxng = etree.RelaxNG(relaxng_doc)

>>> valid = StringIO('<a><b></b></a>')
>>> doc = etree.parse(valid)
>>> relaxng.validate(doc)
True

>>> invalid = StringIO('<a><c></c></a>')
>>> doc2 = etree.parse(invalid)
>>> relaxng.validate(doc2)
False
18

你觉得用 lxml 这个库怎么样?

根据文档的介绍:

>>> f = StringIO('''\
... <element name="a" xmlns="http://relaxng.org/ns/structure/1.0">
...  <zeroOrMore>
...     <element name="b">
...       <text />
...     </element>
...  </zeroOrMore>
... </element>
... ''')
>>> relaxng_doc = etree.parse(f)
>>> relaxng = etree.RelaxNG(relaxng_doc)

>>> valid = StringIO('<a><b></b></a>')
>>> doc = etree.parse(valid)
>>> relaxng.validate(doc)
True

>>> invalid = StringIO('<a><c></c></a>')
>>> doc2 = etree.parse(invalid)
>>> relaxng.validate(doc2)
False

撰写回答