I am currently using lxml
and want to validate a XML content.
I wrote it completely in Python from tei = etree.Element("TEI", nsmap={None: 'http://www.tei-c.org/ns/1.0'}
with many subelements.
At a moment, I want to check if the structure is ok using a specific .xsd
file using the following code:
xmlschema_doc = etree.parse(xsd_file_path)
xmlschema = etree.XMLSchema(xmlschema_doc)
# run check
status = xmlschema.validate(xml_tree)
It returns False with error Element 'TEI': No matching global declaration available for the validation root.
I observe a very weird thing that if I write the xml using
ET = etree.ElementTree(xmlData)
ET.write('test.xml', pretty_print=True, xml_declaration=True, encoding='utf-8')
and if I reopen it with b= etree.parse('test.xml')
I finally had no error and the xml structure is valid as a result of xmlschema.validate(b)
Any idea about what I need to add in my xml structure?
EDIT: First items in the not valid XML
First items in the valid XML file
EDIT:
<?xml version='1.0' encoding='UTF-8'?>
<TEI xmlns="http://www.tei-c.org/ns/1.0">
<text>
<body>
<listBibl>
<biblFull>
<titleStmt>
<title xml:lang="en">article</title>
<title xml:lang="fr">article</title>
<title type="sub" xml:lang="en">A subtitle</title>
<author role="aut">
<persName>
<forename type="first">John</forename>
<surname>Doe</surname>
</persName>
<email>email</email>
<idno type="http://orcid.org/">orcid</idno>
<affiliation ref="#localStruct-affiliation"/>
<affiliation ref="#struct-affiliation"/>
</author>
<author role="aut">
<persName>
<forename type="first">Jane</forename>
<forename type="middle">Middle</forename>
<surname>Doe</surname>
</persName>
<email>email</email>
<idno type="http://orcid.org/">orcid</idno>
<affiliation ref="#localStruct-affiliationA"/>
<affiliation ref="#localStruct-affiliationB"/>
</author>
</titleStmt>
<editionStmt>
<edition>
<ref type="file" subtype="author" n="1" target="upload.pdf"/>
</edition>
</editionStmt>
<publicationStmt>
<availability>
<licence target="https://creativecommons.org/licenses//cc-by/"/>
</availability>
</publicationStmt>
<notesStmt>
<note type="audience" n="2"/>
<note type="invited" n="1"/>
<note type="popular" n="0"/>
<note type="peer" n="1"/>
<note type="proceedings" n="0"/>
<note type="commentary">small comment</note>
<note type="description">small description</note>
</notesStmt>
<sourceDesc>
<biblStruct>
<analytic>
<title xml:lang="en">article</title>
<title xml:lang="fr">article</title>
<title type="sub" xml:lang="en">A subtitle</title>
<author role="aut">
<persName>
<forename type="first">John</forename>
<surname>Doe</surname>
</persName>
<email>email</email>
<idno type="http://orcid.org/">orcid</idno>
<affiliation ref="#localStruct-affiliation"/>
<affiliation ref="#struct-affiliation"/>
</author>
<author role="aut">
<persName>
<forename type="first">Jane</forename>
<forename type="middle">Middle</forename>
<surname>Doe</surname>
</persName>
<email>email</email>
<idno type="http://orcid.org/">orcid</idno>
<affiliation ref="#localStruct-affiliationA"/>
<affiliation ref="#localStruct-affiliationB"/>
</author>
</analytic>
<monogr>
<idno type="isbn">978-1725183483</idno>
<idno type="halJournalId">117751</idno>
<idno type="issn">xxx</idno>
<imprint>
<publisher>springer</publisher>
<biblScope unit="serie">a special collection</biblScope>
<biblScope unit="volume">20</biblScope>
<biblScope unit="issue">1</biblScope>
<biblScope unit="pp">10-25</biblScope>
<date type="datePub">2024-01-01</date>
</imprint>
</monogr>
<series/>
<idno type="doi">reg</idno>
<idno type="arxiv">ger</idno>
<idno type="bibcode">erg</idno>
<idno type="ird">greger</idno>
<idno type="pubmed">greger</idno>
<idno type="ads">gaergezg</idno>
<idno type="pubmedcentral">gegzefdv</idno>
<idno type="irstea">vvxc</idno>
<idno type="sciencespo">gderg</idno>
<idno type="oatao">gev</idno>
<idno type="ensam">xcvcxv</idno>
<idno type="prodinra">vxcv</idno>
<ref type="publisher">https://publisher.com/ID</ref>
<ref type="seeAlso">https://link1.com/ID</ref>
<ref type="seeAlso">https://link2.com/ID</ref>
<ref type="seeAlso">https://link3.com/ID</ref>
</biblStruct>
</sourceDesc>
<profileDesc>
<textClass>
<keywords scheme="author">
<term xml:lang="en">keyword1</term>
<term xml:lang="en">keyword2</term>
<term xml:lang="fr">mot-clé1</term>
<term xml:lang="fr">mot-clé2</term>
</keywords>
<classCode scheme="halDomain" n="physics"/>
<classCode scheme="halDomain" n="halDomain2"/>
<classCode scheme="halTypology" n="ART"/>
</textClass>
</profileDesc>
</biblFull>
</listBibl>
</body>
<back>
<listOrg type="structures">
<org type="institution" xml:id="localStruct-affiliation">
<orgName>laboratory for MC, university of Yeah</orgName>
<orgName type="acronym">LMC</orgName>
<desc>
<address>
<addrLine>Blue street 155, 552501 Olso, Norway</addrLine>
<country key="LS">Lesotho</country>
</address>
<ref type="url" target="https://lmc.univ-yeah.com"/>
</desc>
</org>
<org type="institution" xml:id="localStruct-affiliationB">
<orgName>laboratory for MCL, university of Yeah</orgName>
<orgName type="acronym">LMCL</orgName>
<desc>
<address>
<addrLine>Blue street 155, 552501 Olso, Norway</addrLine>
<country key="NO">Norway</country>
</address>
<ref type="url" target="https://lmcl.univ-yeah.com"/>
</desc>
</org>
</listOrg>
</back>
</text>
</TEI>
Have a look at https://lxml.de/tutorial.html#namespaces, you should basically use
TEI_NAMESPACE = "http://www.tei-c.org/ns/1.0"
TEI = "{%s}" % TEI_NAMESPACE
NSMAP = {None : TEI_NAMESPACE} # the default namespace (no prefix)
root = etree.Element(TEI + "TEI", nsmap=NSMAP) # lxml only!
text = etree.SubElement(root, TEI + "text")
and so on for all elements, to ensure they are created in the TEI namespace.
A minimal in memory created ElementTree to be valid against the schema (after I downloaded it together with the imported W3C xml.xsd) is e.g.
from lxml import etree
TEI_NAMESPACE = "http://www.tei-c.org/ns/1.0"
TEI = "{%s}" % TEI_NAMESPACE
NSMAP = {None : TEI_NAMESPACE} # the default namespace (no prefix)
root = etree.Element(TEI + "TEI", nsmap=NSMAP) # lxml only!
text = etree.SubElement(root, TEI + "text")
body = etree.SubElement(text, TEI + "body")
listBibl = etree.SubElement(body, TEI + "listBibl")
biblFull = etree.SubElement(listBibl, TEI + "biblFull")
sourceDesc = etree.SubElement(biblFull, TEI + "sourceDesc")
profileDesc = etree.SubElement(biblFull, TEI + "profileDesc")
xmlschema_doc = etree.parse("aofr.xsd")
xmlschema = etree.XMLSchema(xmlschema_doc)
# run check
status = xmlschema.validate(root)
print(status)
print(xmlschema.error_log)