如何用Python将XSD中的文档注释添加到对应XML元素上方?
从XSD提取注释并添加到XML对应元素
需求说明
现有如下XSD Schema和对应的XML文件,XML文件未包含任何文档注释,需要用Python实现将XSD中的文档注释添加到XML对应元素的上方。
提供的XSD内容
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://tempuri.org/PurchaseOrderSchema.xsd" targetNamespace="http://tempuri.org/PurchaseOrderSchema.xsd" elementFormDefault="qualified"> <xsd:element name="PurchaseOrder" type="tns:PurchaseOrderType"/> <xsd:complexType name="PurchaseOrderType"> <xsd:annotation> <xsd:documentation xml:lang="en"> purchasing products </xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:element name="ShipTo" type="tns:USAddress" maxOccurs="2"/> <xsd:element name="BillTo" type="tns:USAddress"/> </xsd:sequence> <xsd:attribute name="OrderDate" type="xsd:date"/> </xsd:complexType> <xsd:complexType name="USAddress"> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> <xsd:element name="street" type="xsd:string"/> <xsd:element name="city" type="xsd:string"/> <xsd:element name="state" type="xsd:string"/> <xsd:element name="zip" type="xsd:integer"/> </xsd:sequence> <xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US"/> </xsd:complexType> </xsd:schema>
提供的XML内容
<?xml version="1.0" encoding="utf-8"?> <PurchaseOrder OrderDate="2012-12-13"> <ShipTo country="US"> <name>sam</name> <street>paul</street> <city>ny</city> <state>ny</state> <zip>1234</zip> </ShipTo> <BillTo country="US"> <name>sarah</name> <street>missa</street> <city>ny</city> <state>ny</state> <zip>125</zip> </BillTo> </PurchaseOrder>
实现方案
我们使用lxml库处理XSD和XML的解析与修改,步骤如下:
1. 安装依赖库
执行以下命令安装lxml:
pip install lxml
2. Python代码实现
from lxml import etree def extract_xsd_comments(xsd_content): """从XSD中提取元素名称与对应注释的映射""" comment_map = {} xsd_tree = etree.fromstring(xsd_content) xsd_ns = {'xsd': 'http://www.w3.org/2001/XMLSchema'} # 匹配全局元素对应的complexType注释 for elem in xsd_tree.xpath('xsd:element', namespaces=xsd_ns): elem_name = elem.get('name') type_name = elem.get('type') if type_name and type_name.startswith('tns:'): complex_type_name = type_name.split(':')[1] # 查找对应complexType的注释 complex_type = xsd_tree.xpath(f'xsd:complexType[@name="{complex_type_name}"]', namespaces=xsd_ns) if complex_type: doc_node = complex_type[0].xpath('xsd:annotation/xsd:documentation', namespaces=xsd_ns) if doc_node: comment = doc_node[0].text.strip() comment_map[elem_name] = comment return comment_map def add_comments_to_xml(xml_content, comment_map): """将注释插入到XML对应元素的上方""" xml_tree = etree.fromstring(xml_content, etree.XMLParser(remove_blank_text=True)) # 遍历所有元素,匹配注释并插入 for elem in xml_tree.iter(): elem_name = elem.tag if elem_name in comment_map: comment_node = etree.Comment(f' {comment_map[elem_name]} ') elem.addprevious(comment_node) # 格式化输出XML return etree.tostring(xml_tree, encoding='utf-8', pretty_print=True, xml_declaration=True).decode('utf-8') # 定义XSD和XML内容(实际使用时可从文件读取) xsd_content = """<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://tempuri.org/PurchaseOrderSchema.xsd" targetNamespace="http://tempuri.org/PurchaseOrderSchema.xsd" elementFormDefault="qualified"> <xsd:element name="PurchaseOrder" type="tns:PurchaseOrderType"/> <xsd:complexType name="PurchaseOrderType"> <xsd:annotation> <xsd:documentation xml:lang="en"> purchasing products </xsd:documentation> </xsd:annotation> <xsd:sequence> <xsd:element name="ShipTo" type="tns:USAddress" maxOccurs="2"/> <xsd:element name="BillTo" type="tns:USAddress"/> </xsd:sequence> <xsd:attribute name="OrderDate" type="xsd:date"/> </xsd:complexType> <xsd:complexType name="USAddress"> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> <xsd:element name="street" type="xsd:string"/> <xsd:element name="city" type="xsd:string"/> <xsd:element name="state" type="xsd:string"/> <xsd:element name="zip" type="xsd:integer"/> </xsd:sequence> <xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US"/> </xsd:complexType> </xsd:schema>""" xml_content = """<?xml version="1.0" encoding="utf-8"?> <PurchaseOrder OrderDate="2012-12-13"> <ShipTo country="US"> <name>sam</name> <street>paul</street> <city>ny</city> <state>ny</state> <zip>1234</zip> </ShipTo> <BillTo country="US"> <name>sarah</name> <street>missa</street> <city>ny</city> <state>ny</state> <zip>125</zip> </BillTo> </PurchaseOrder>""" # 执行处理流程 comment_map = extract_xsd_comments(xsd_content) modified_xml = add_comments_to_xml(xml_content, comment_map) # 输出结果 print(modified_xml)
3. 最终输出效果
运行代码后,生成的XML会在对应元素上方添加注释:
<?xml version='1.0' encoding='utf-8'?> <!-- purchasing products --> <PurchaseOrder OrderDate="2012-12-13"> <ShipTo country="US"> <name>sam</name> <street>paul</street> <city>ny</city> <state>ny</state> <zip>1234</zip> </ShipTo> <BillTo country="US"> <name>sarah</name> <street>missa</street> <city>ny</city> <state>ny</state> <zip>125</zip> </BillTo> </PurchaseOrder>
扩展说明
如果需要处理子元素的注释,可以扩展extract_xsd_comments函数,遍历XSD中所有xsd:element节点,提取其内部的xsd:documentation内容,建立更全面的注释映射。
内容的提问来源于stack exchange,提问作者Sam12
相关产品推荐
相关产品推荐

