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

XML响应XSD验证触发SAXParseException错误,求解决方案

SOAP接口XML响应XSD验证报错:Premature end of file

问题描述

对SOAP接口返回的XML响应进行XSD验证时,触发org.xml.sax.SAXParseException错误,错误信息显示“Premature end of file”,关联的systemId为http://schemas.xmlsoap.org/soap/envelope/。已将该链接对应的XSD文件下载到项目src/main/resources目录,但问题仍未解决。

错误日志

HTTP/1.1 200 OK Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Content-Encoding: gzip
Vary: Accept-Encoding
Server: Microsoft-IIS/10.0
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET
X-Powered-By-Plesk: PleskWin
Date: Thu, 31 Jul 2025 06:25:36 GMT
Content-Length: 348

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <AddResponse xmlns="http://tempuri.org/">
      <AddResult>5</AddResult>
    </AddResponse>
  </soap:Body>
</soap:Envelope>
FAILED: tests.XMLSchemaValidation.schemaValidation
org.xml.sax.SAXParseException; systemId: http://schemas.xmlsoap.org/soap/envelope/; lineNumber: 1; columnNumber: 1; Premature end of file.
    at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:204)
    at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:178)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:400)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:327)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1465)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:1043)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:635)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:113)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:551)
    at java.xml/com.sun.org.apache.xerces.internal.impl.xs.opti.SchemaParsingConfig.parse(SchemaParsingConfig.java:640)
    at java.xml/com.sun.org.apache.xerces.internal.impl.xs.opti.SchemaParsingConfig.parse(SchemaParsingConfig.java:696)
    at java.xml/com.sun.org.apache.xerces.internal.impl.xs.opti.SchemaDOMParser.parse(SchemaDOMParser.java:530)
    at java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.getSchemaDocument(XSDHandler.java:2227)
    at java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.resolveSchema(XSDHandler.java:2129)
    at java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.constructTrees(XSDHandler.java:1050)
    at java.xml/com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.parseSchema(XSDHandler.java:653)
    at java.xml/com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadSchema(XMLSchemaLoader.java:617)
    at java.xml/com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:576)
    at java.xml/com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:542)
    at java.xml/com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory.newSchema(XMLSchemaFactory.java:278)
    at java.xml/javax.xml.validation.SchemaFactory.newSchema(SchemaFactory.java:612)
    at javax.xml.validation.SchemaFactory$newSchema$0.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:139)
    at io.restassured.internal.matcher.xml.XmlXsdMatcher.matches(XmlXsdMatcher.groovy:82)
    at io.restassured.internal.assertion.BodyMatcher.validate(BodyMatcher.java:82)
    at io.restassured.internal.assertion.BodyMatcherGroup.lambda$validate$0(BodyMatcherGroup.java:30)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:215)
    at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1716)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:570)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:560)
    at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:265)
    at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:727)
    at io.restassured.internal.assertion.BodyMatcherGroup.validate(BodyMatcherGroup.java:30)
    at io.restassured.internal.assertion.BodyMatcherGroup$validate$3.call(Unknown Source)
    at io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure.validate(ResponseSpecificationImpl.groovy:499)
    at io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure$validate$1.call(Unknown Source)
    at io.restassured.internal.ResponseSpecificationImpl.validateResponseIfRequired(ResponseSpecificationImpl.groovy:696)
    at io.restassured.internal.ResponseSpecificationImpl.this$2$validateResponseIfRequired(ResponseSpecificationImpl.groovy)
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
    at java.base/java.lang.reflect.Method.invoke(Method.java:565)
    at org.codehaus.groovy.runtime.callsite.PlainObjectMetaMethodSite.doInvoke(PlainObjectMetaMethodSite.java:43)
    at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:198)
    at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:62)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:171)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:185)
    at io.restassured.internal.ResponseSpecificationImpl.body(ResponseSpecificationImpl.groovy:107)
    at io.restassured.internal.ValidatableResponseOptionsImpl.body(ValidatableResponseOptionsImpl.java:238)
    at tests.XMLSchemaValidation.schemaValidation(XMLSchemaValidation.java:48)
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
    at java.base/java.lang.reflect.Method.invoke(Method.java:565)
    at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:141)
    at org.testng.internal.invokers.TestInvoker.invokeMethod(TestInvoker.java:687)
    at org.testng.internal.invokers.TestInvoker.invokeTestMethod(TestInvoker.java:230)
    at org.testng.internal.invokers.MethodRunner.runInSequence(MethodRunner.java:63)
    at org.testng.internal.invokers.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:995)
    at org.testng.internal.invokers.TestInvoker.invokeTestMethods(TestInvoker.java:203)
    at org.testng.internal.invokers.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:154)
    at org.testng.internal.invokers.TestMethodWorker.run(TestMethodWorker.java:134)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1604)
    at org.testng.TestRunner.privateRun(TestRunner.java:741)
    at org.testng.TestRunner.run(TestRunner.java:616)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:421)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:413)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:373)
    at org.testng.SuiteRunner.run(SuiteRunner.java:312)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1274)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1208)
    at org.testng.TestNG.runSuites(TestNG.java:1112)
    at org.testng.TestNG.run(TestNG.java:1079)
    at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115)
    at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:293)
    at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:91)

测试代码

File file = new File("./SoapRequests/add.xml");
if(file.exists())
{
    System.out.println(">>>>  File Exists  <<<<");
}

FileInputStream fileinputstream = new FileInputStream(file);
String requestBody = IOUtils.toString(fileinputstream, "UTF-8");

baseURI = "http://www.dneonline.com";

given().
    contentType("text/xml").
    accept(ContentType.XML).
    body(requestBody).
when().
    post("/calculator.asmx").
then().
    statusCode(200).
    log().all().
and().
    body("//*:AddResult.text()", equalTo("5")).
and().
    assertThat().body(matchesXsdInClasspath("Calculator.xsd"));

请求XML文件

<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <Add xmlns="http://tempuri.org/">
      <intA>2</intA>
      <intB>3</intB>
    </Add>
  </soap:Body>
</soap:Envelope>

使用的XSD文件

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://tempuri.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:import namespace="http://schemas.xmlsoap.org/soap/envelope/"   
           schemaLocation="http://schemas.xmlsoap.org/soap/envelope/"/>
  <xs:element name="AddResponse">
    <xs:complexType>
      <xs:sequence>
        <xs:element type="xs:byte" name="AddResult"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

解决方案

错误原因

XSD文件中<xs:import>的schemaLocation仍指向远程地址,解析器尝试从该地址下载SOAP信封XSD时,因网络或访问限制导致下载失败,返回空内容,触发“Premature end of file”错误。即使已下载本地XSD文件,解析器也未使用。

修复步骤

  1. 修改XSD的import路径:将Calculator.xsd中的<xs:import>语句的schemaLocation改为本地XSD文件名。假设下载的SOAP信封XSD文件名为soap-envelope.xsd,且与Calculator.xsd同处于src/main/resources目录,修改后代码如下:
<xs:import namespace="http://schemas.xmlsoap.org/soap/envelope/" schemaLocation="soap-envelope.xsd"/>
  1. 确认本地XSD位置:确保soap-envelope.xsd确实放在src/main/resources目录下,编译后能被类路径加载。
  2. 重新运行测试:此时解析器会从本地类路径加载导入的XSD文件,无需访问远程地址,即可完成XML响应的验证。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 14:52:32