根据lxml文档“DTD是根据解析文档的DOCTYPE自动检索的。您所要做的就是使用启用了DTD验证的解析器。”
http://lxml.de/validation.html#validation-at-parse-time
但是,如果要对XML架构进行验证,则需要显式引用一个。
我想知道为什么会这样,并且想知道是否有可以执行此操作的库或函数。或者甚至解释如何让自己发生这种情况。问题是似乎有很多方法可以引用XSD,我需要支持所有这些。
验证不是问题。问题是如何确定要验证的模式。理想情况下,这也会处理内联架构。
更新
这是一个例子。
simpletest.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="name" type="xs:string"/>
</xs:schema>
simpletest.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<name xmlns="http://www.example.org"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.org simpletest.xsd">foo</name>
我想做以下事情:
>>> parser = etree.XMLParser(xsd_validation=True)
>>> tree = etree.parse("simpletest.xml", parser)
答案 0 :(得分:2)
我的项目有100多种不同的模式和xml树。为了管理所有这些并验证它们,我做了一些事情。
1)我创建了一个文件(即xmlTrees.py),其中我创建了每个xml的字典以及与之关联的相应模式,以及xml路径。这让我有一个地方可以同时获得xml和用于验证xml的模式。
MY_XML = {'url':'/pathToTree/myTree.xml', 'schema':'myXSD.xsd'}
2)在项目中,我们拥有同样多的名称空间(非常难以管理)。所以我又做了一次,我创建了一个单独的文件,其中包含lxml喜欢的格式的所有命名空间。然后在我的测试和脚本中,我将始终传递命名空间的超集。
ALL_NAMESPACES = {
'namespace1': 'http://www.example.org',
'namespace2': 'http://www.example2.org'
}
3)对于基本/通用验证,我最终创建了一个我可以调用的基本功能:
def validateXML(content, schemaContent):
try:
xmlSchema_doc = etree.parse(schemaContent);
xmlSchema = etree.XMLSchema(xmlSchema_doc);
xml = etree.parse(StringIO(content));
except:
logging.critical("Could not parse schema or content to validate xml");
response['valid'] = False;
response['errorlog'] = "Could not parse schema or content to validate xml";
response = {}
# Validate the content against the schema.
try:
xmlSchema.assertValid(xml)
response['valid'] = True
response['errorlog'] = None
except etree.DocumentInvalid, info:
response['valid'] = False
response['errorlog'] = xmlSchema.error_log
return response
基本上任何想要使用它的函数都需要将xml内容和xsd内容作为字符串发送。这为我提供了最大的灵活性。然后我把这个函数放在一个文件中,我有我所有的xml帮助函数。
答案 1 :(得分:1)
您可以自己提取模式并将其导入根模式:
from lxml import etree
XSI = "http://www.w3.org/2001/XMLSchema-instance"
XS = '{http://www.w3.org/2001/XMLSchema}'
SCHEMA_TEMPLATE = """<?xml version = "1.0" encoding = "UTF-8"?>
<xs:schema xmlns="http://dummy.libxml2.validator"
targetNamespace="http://dummy.libxml2.validator"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="1.0"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
</xs:schema>"""
def validate_XML(xml):
"""Validate an XML file represented as string. Follow all schemaLocations.
:param xml: XML represented as string.
:type xml: str
"""
tree = etree.XML(xml)
schema_tree = etree.XML(SCHEMA_TEMPLATE)
# Find all unique instances of 'xsi:schemaLocation="<namespace> <path-to-schema.xsd> ..."'
schema_locations = set(tree.xpath("//*/@xsi:schemaLocation", namespaces={'xsi': XSI}))
for schema_location in schema_locations:
# Split namespaces and schema locations ; use strip to remove leading
# and trailing whitespace.
namespaces_locations = schema_location.strip().split()
# Import all found namspace/schema location pairs
for namespace, location in zip(*[iter(namespaces_locations)] * 2):
xs_import = etree.Element(XS + "import")
xs_import.attrib['namespace'] = namespace
xs_import.attrib['schemaLocation'] = location
schema_tree.append(xs_import)
# Contstruct the schema
schema = etree.XMLSchema(schema_tree)
# Validate!
schema.assertValid(tree)
BTW,你的simpletest.xsd缺少targetNamespace。
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org" elementFormDefault="qualified">
<xs:element name="name" type="xs:string"/>
</xs:schema>
使用上面的代码,您的示例文档将针对此架构进行验证。