如何使用 lxml 在 XML Header 中声明模式

How to Declare Schemas in your XML Header using lxml

我希望我的 XML 看起来像这样,开头有两个关联的模式:

<?xml version="1.0" encoding="utf-8"?>
<?xml-model href="https://raw.githubusercontent.com/LTAC-Global/TBX-Core_dialect/master/Schemas/TBXcoreStructV03_TBX-Core_integrated.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="https://raw.githubusercontent.com/LTAC-Global/TBX-Core_dialect/master/Schemas/TBX-Core.sch" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<body>...</body>

如何使用 python 中的 lxml 库实现此目的:

from lxml import etree
root = etree.Element("body")

我知道第一行是使用

添加的
etree.tostring(root, encoding='utf-8', xml_declaration=True, pretty_print=True)

“第一行”

<?xml version="1.0" encoding="utf-8"?>

是 XML 声明。它是一个特殊的结构,在 XML 文件中只能存在一次,其唯一目的是通知接收端的 XML 解析器它将要查看的内容。一旦解析器使用了文件并创建了文档树,它就会消失。正如您所发现的,您将其设置为如何将树转换为字符串的选项。

其他行是处理指令。它们看起来很相似,但它们在概念上是不同的。它们是文档树中的 实际节点 ,就像 <body>...</body>.

<?xml-model href="https://raw.githubusercontent.com/LTAC-Global/TBX-Core_dialect/master/Schemas/TBXcoreStructV03_TBX-Core_integrated.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="https://raw.githubusercontent.com/LTAC-Global/TBX-Core_dialect/master/Schemas/TBX-Core.sch" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<body>...</body>

这意味着有一个创建它们的函数,就像有一个创建元素的函数一样。处理指令有一个名称和一个值。该值允许看起来像属性,但它实际上只是一个字符串,它可以是任何东西:

root = etree.Element("body")
tree = etree.ElementTree(root)

pi1 = etree.ProcessingInstruction('xml-model', 'href="https://raw.githubusercontent.com/LTAC-Global/TBX-Core_dialect/master/Schemas/TBXcoreStructV03_TBX-Core_integrated.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"') 
pi2 = etree.ProcessingInstruction('it-could-be', 'anything, really') 

一旦创建,您就可以像添加任何其他节点一样将它们添加到文档树中,例如“在根元素之前”:

 tree.getroot().addprevious(pi1)
 tree.getroot().addprevious(pi2)

在每个文本节点后显式添加带有换行符 ('\n') 的文本节点,或使用 etree.tostring(tree, pretty_print=True) 将输出格式化为行。

上面的代码产生了这个(缺少 XML 声明,因为我没有在 tree.tostring() 中打开它):

<?xml-model href="https://raw.githubusercontent.com/LTAC-Global/TBX-Core_dialect/master/Schemas/TBXcoreStructV03_TBX-Core_integrated.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?it-could-be anything, really?>
<body/>

顺便说一句,处理指令是 PHP 从以下位置获取其标记语法的地方:<?php a bunch of PHP code here ?> - 它们的字面意思是提供一种包含如何处理 XML 树的指令的方法。