当我尝试通过架构使用 DocumentBuilderFactory 验证 xml 文件时,我收到错误“找不到元素的声明”

Posted

技术标签:

【中文标题】当我尝试通过架构使用 DocumentBuilderFactory 验证 xml 文件时,我收到错误“找不到元素的声明”【英文标题】:When i try to validate xml file using DocumentBuilderFactory by schema i recieve error "Cannot find the declaration of element " 【发布时间】:2021-07-20 04:15:30 【问题描述】:

我有一个名为 input.xml 的 xml 文件

它包含以下代码

<?xml version="1.0"?>
<tests xmlns="http://www.example.com/Report"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.example.com/Report input.xsd">
    <test id="1">
        <coverage>65</coverage>
        <usedFramework>Junit4</usedFramework>
        <typeTest>Integration</typeTest>
    </test>
    <test id="2">
        <coverage>35</coverage>
        <usedFramework>Junit5</usedFramework>
        <typeTest>Module</typeTest>
    </test>
    <test id="3">
        <coverage>45</coverage>
        <usedFramework>Mockito</usedFramework>
        <typeTest>Integration</typeTest>
    </test>
</tests>

我还有名为 input.std 的 XML 架构 XML Schema 文件如下所示

<?xml version="1.0"?>
<xs:schema targetNamespace="http://www.example.com/Report"
           xmlns="http://www.example.com/Report"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified">
    <xs:element name="tests">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="test" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="coverage" type="xs:positiveInteger"/>
                            <xs:element name="usedFramework" type="xs:string"/>
                            <xs:element name="typeTest" type="xs:string"/>
                        </xs:sequence>
                        <xs:attribute name="id" type="xs:positiveInteger"/>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

</xs:schema>

接下来的代码会写在java上

try 
          File schemaFile = new File("input.xsd");
            SchemaFactory schemaFactory = SchemaFactory
                    .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
                Schema schema = schemaFactory.newSchema(schemaFile);

            File inputXml = new File(xmlPath);
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
            factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
            factory.setSchema(schema);
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(inputXml);
            List<Test> list = new ArrayList<>();
            NodeList tests = document.getElementsByTagName("test");
            for(int i=0;i< tests.getLength();i++)
                Element element = (Element) tests.item(i);
                if(element.getNodeType()==Node.ELEMENT_NODE)
                    int coverage = Integer.parseInt(element.getElementsByTagName("coverage").item(0).getTextContent());
                    int id = Integer.parseInt(element.getAttribute("id"));
                    String usedFramework = (element.getElementsByTagName("usedFramework").item(0).getTextContent());
                    String typeTest = (element).getElementsByTagName("typeTest").item(0).getTextContent();
                    list.add(new Test(id,coverage,usedFramework,typeTest));
                
            
            list.sort(Comparator.comparing(Test::getCoverage));
            list.forEach(System.out::println);

        catch (ParserConfigurationException | IOException | SAXException e)
            
            Logger.getLogger(XmlReader.class.getName()).log(Level.INFO,e.getMessage());

        

当我尝试运行应用程序时发生错误

那么我哪里出错了?我查看了“如何正确引用本地 XML Schema 文件?”在不同的问题上,没有看到任何错误,你能帮我解决它们吗?

【问题讨论】:

请尝试为您的代码中的输入 XML 文件和架构提供完全限定的路径。 在您的描述中,您有“input._std_”,而在您的代码中,它是“input._xsd_”。这只是一个错字吗?你确定路径是正确的吗?例如,它可能存储在“resources/input.xsd”下? 我已经发现错误了。我必须调用 DocumentBuilderFactory 的方法 setNamespaceAware 并将 true 作为参数传递 【参考方案1】:

我必须调用 DocumentBuilderFactory 的方法 setNamespaceAware 并将 true 作为参数传递

// parse an XML document into a DOM tree
DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = parser.parse(new File("example.xml"));

问题在于 DocumentBuilder 默认情况下不支持命名空间。以下附加更改解决了该问题:

// parse an XML document into a DOM tree
DocumentBuilderFactory dmfactory = DocumentBuilderFactory.newInstance();
dmfactory.setNamespaceAware(true);
DocumentBuilder parser = dmfactory.newDocumentBuilder();
Document document = parser.parse(new File("example.xml"));

【讨论】:

以上是关于当我尝试通过架构使用 DocumentBuilderFactory 验证 xml 文件时,我收到错误“找不到元素的声明”的主要内容,如果未能解决你的问题,请参考以下文章

当我在 3 层架构中使用 ado.net 模型并尝试将数据从 DAL 加载到 UI 时,它会在 UI app.config 中询问连接字符串

如何将嵌套字段添加到我的 BigQuery 表架构?

GraphQL 文档资源管理器未加载我的架构

ActiveRecord 将在迁移时创建数据库,但当我尝试保存某些内容或生成架构时找不到它

Spring批处理xmlns架构错误

Pyspark 从 JSON 文件中获取 Schema