You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Schema验证XML失败,但读取写入文件后验证成功

问题描述

我用lxml工具验证XML内容,通过Python代码构造了带TEI命名空间的XML结构:

tei = etree.Element("TEI", nsmap={None: 'http://www.tei-c.org/ns/1.0'})

随后用指定XSD文件验证时,执行以下代码:

xmlschema_doc = etree.parse(xsd_file_path)
xmlschema = etree.XMLSchema(xmlschema_doc)
# 执行检查
status = xmlschema.validate(xml_tree)

返回False,错误信息为:Element 'TEI': No matching global declaration available for the validation root.

但出现一个特殊情况:如果把XML写入文件:

ET = etree.ElementTree(xmlData)
ET.write('test.xml', pretty_print=True, xml_declaration=True, encoding='utf-8')

再用b= etree.parse('test.xml')读取文件,执行xmlschema.validate(b)就能验证通过,说明XML结构本身合法。

请问需要在XML结构中添加什么内容来解决这个问题?

补充信息:

  • 未验证通过的XML开头:<TEI xmlns="http://www.tei-c.org/ns/1.0">
  • 验证通过的XML文件开头:<?xml version='1.0' encoding='UTF-8'?><TEI xmlns="http://www.tei-c.org/ns/1.0">

完整XML示例:

<?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>
解决方案

问题核心是内存中构造的XML元素未正确绑定命名空间与全局元素声明的关联,写入文件再读取时lxml会重新解析并自动修正这个关联。不需要修改XML结构,只需调整构造或验证方式:

方法1:序列化后重新解析

把内存中的XML序列化为字符串,再解析成树结构后验证:

xml_str = etree.tostring(xml_tree, encoding='utf-8', xml_declaration=True)
parsed_tree = etree.fromstring(xml_str)
status = xmlschema.validate(parsed_tree)

方法2:确保子元素继承根元素命名空间

构造子元素时,不要直接用etree.Element("text"),而是通过根元素的makeelement方法创建,或显式指定命名空间,确保所有子元素都属于TEI命名空间:

# 方式1:用根元素的makeelement方法创建子元素
text = tei.makeelement("text")
tei.append(text)

# 方式2:显式指定命名空间
text = etree.Element("{http://www.tei-c.org/ns/1.0}text")
tei.append(text)

如果之前构造子元素未指定命名空间,会导致子元素属于无命名空间,虽然根元素有命名空间,但XSD验证会判定结构不合法。写入文件再读取时,lxml会默认将无命名空间子元素归到根元素的默认命名空间下,因此验证通过。

方法3:用assertValid获取详细错误

若仍有问题,用xmlschema.assertValid(xml_tree)抛出详细异常,定位具体不符合命名空间要求的元素。


内容的提问来源于stack exchange,提问作者Guuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 00:49:50