嗨,我现在正在 Spring Boot 上开发 xml 验证器,但它并没有给我提供与使用在线工具验证时相同的结果,即使我一直使用相同的 .sch 文件和 .xml 文件。有人可以帮忙吗?
我创建了一个 xml 验证器 api
ValidationController.java
package com.example.peppol_validator.controller;
import com.example.peppol_validator.service.XmlValidationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;
import org.xml.sax.SAXException;
import java.io.IOException;
@RestController
@RequestMapping("/api/validate")
public class ValidationController {
@Autowired
private final XmlValidationService xmlValidationService;
public ValidationController(XmlValidationService xmlValidationService) {
this.xmlValidationService = xmlValidationService;
}
@PostMapping
public ResponseEntity<String> validateXml(@RequestParam("xmlFile") String xmlFile,
@RequestParam("schemaFile") String schemaFile) {
try {
xmlValidationService.validateXml(xmlFile, schemaFile);
return ResponseEntity.ok("XML is valid.");
} catch (SAXException e) {
return ResponseEntity.badRequest().body("Validation error: " + e.getMessage());
} catch (IOException e) {
return ResponseEntity.badRequest().body("IO error: " + e.getMessage());
}
}
}
XmlValidationService
package com.example.peppol_validator.service;
import org.apache.xerces.parsers.DOMParser;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import org.xml.sax.InputSource;
import java.io.IOException;
import java.io.InputStream;
@Service
public class XmlValidationService {
private final ResourceLoader resourceLoader;
public XmlValidationService(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
public void validateXml(String xmlPath, String schemaPath) throws IOException, SAXException {
Resource xmlResource = resourceLoader.getResource("classpath:" + xmlPath);
Resource schemaResource = resourceLoader.getResource("classpath:" + schemaPath);
try (InputStream xmlInputStream = xmlResource.getInputStream();
InputStream schemaInputStream = schemaResource.getInputStream()) {
DOMParser parser = new DOMParser();
parser.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
parser.setFeature("http://xml.org/sax/features/validation", true);
parser.setFeature("http://apache.org/xml/features/validation/schema", true);
parser.setFeature("http://apache.org/xml/features/validation/schema-full-checking", true);
// Set the schema for validation
parser.setProperty("http://apache.org/xml/properties/schema/external-schemaLocation", schemaResource.getURL().toString());
// Use the schema input stream for validation
parser.setProperty("http://apache.org/xml/properties/schema/external-schemaLocation", schemaPath);
parser.parse(new InputSource(xmlInputStream)); // Change here
System.out.println("XML is valid.");
} catch (SAXParseException e) {
System.out.println("XML is not valid. Error: " + e.getMessage());
throw e;
} catch (SAXException e) {
System.out.println("XML validation error: " + e.getMessage());
throw e;
}
}
}
样本.xml
<ns4:Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:ns2="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
xmlns:ns3="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:ns4="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<CustomizationID>urn:peppol:pint:billing-1@my-1</CustomizationID>
<ProfileID>urn:peppol:bis:billing</ProfileID>
<ID>PMY000676-205-20241024T065854</ID>
<IssueDate>2024-10-24</IssueDate>
<DueDate>2024-11-23</DueDate>
<InvoiceTypeCode>321</InvoiceTypeCode>
<TaxPointDate>2023-11-30</TaxPointDate>
<DocumentCurrencyCode>MYR</DocumentCurrencyCode>
<AccountingCost>ACC:COST:2114</AccountingCost>
<BuyerReference>3789627992</BuyerReference>
<ns3:InvoicePeriod>
<StartDate>2024-10-18</StartDate>
<EndDate>2024-11-22</EndDate>
</ns3:InvoicePeriod>
<ns3:OrderReference>
<ID>PO109831</ID>
<SalesOrderID>793</SalesOrderID>
</ns3:OrderReference>
<ns3:BillingReference>
<ns3:InvoiceDocumentReference>
<ID>53798679</ID>
<IssueDate>2023-11-30</IssueDate>
</ns3:InvoiceDocumentReference>
</ns3:BillingReference>
<ns3:DespatchDocumentReference>
<ID>2100409</ID>
</ns3:DespatchDocumentReference>
<ns3:ReceiptDocumentReference>
<ID>11</ID>
</ns3:ReceiptDocumentReference>
<ns3:OriginatorDocumentReference>
<ID>0965566776</ID>
</ns3:OriginatorDocumentReference>
<ns3:ContractDocumentReference>
<ID>11</ID>
</ns3:ContractDocumentReference>
<ns3:AdditionalDocumentReference>
<ID>Atch56890</ID>
<DocumentDescription>Link to PDF Attchment</DocumentDescription>
<ns3:Attachment>
<ns3:ExternalReference>
<URI>https://thelink</URI>
</ns3:ExternalReference>
</ns3:Attachment>
</ns3:AdditionalDocumentReference>
<ns3:ProjectReference>
<ID>11</ID>
</ns3:ProjectReference>
<ns3:AccountingSupplierParty>
<ns3:Party>
<EndpointID schemeID="0230">051312314</EndpointID>
<ns3:PartyIdentification>
<ID>051312314</ID>
</ns3:PartyIdentification>
<ns3:PartyName>
<Name>Monitor ERP Sdn Bhd</Name>
</ns3:PartyName>
<ns3:PostalAddress>
<StreetName>18, Jalan Excellent</StreetName>
<AdditionalStreetName>Bandar Sunway</AdditionalStreetName>
<CityName>Petaling Jaya</CityName>
<PostalZone>52000</PostalZone>
<CountrySubentity>Sunway</CountrySubentity>
<ns3:AddressLine>
<Line>No 18</Line>
</ns3:AddressLine>
<ns3:Country>
<IdentificationCode>MY</IdentificationCode>
</ns3:Country>
</ns3:PostalAddress>
<ns3:PartyTaxScheme>
<CompanyID>TIN20211100090911</CompanyID>
<ns3:TaxScheme>
<ID>GST</ID>
</ns3:TaxScheme>
</ns3:PartyTaxScheme>
<ns3:PartyTaxScheme>
<CompanyID>SST20211100090911</CompanyID>
<ns3:TaxScheme>
<ID>VAT</ID>
</ns3:TaxScheme>
</ns3:PartyTaxScheme>
<ns3:PartyLegalEntity>
<RegistrationName>Monitor ERP Sdn Bhd</RegistrationName>
<CompanyID>2023010000001</CompanyID>
<CompanyLegalForm>SENDIRIAN BERHAD</CompanyLegalForm>
</ns3:PartyLegalEntity>
<ns3:Contact>
<Name>Ahmad, Danial</Name>
<Telephone>0320334568</Telephone>
<ElectronicMail>[email protected]</ElectronicMail>
</ns3:Contact>
</ns3:Party>
</ns3:AccountingSupplierParty>
<ns3:AccountingCustomerParty>
<ns3:Party>
<EndpointID schemeID="9922">NGTBCNTRLP1001</EndpointID>
<ns3:PartyIdentification>
<ID>NGTBCNTRLP1001</ID>
</ns3:PartyIdentification>
<ns3:PartyName>
<Name>Amazing HQ</Name>
</ns3:PartyName>
<ns3:PostalAddress>
<StreetName>Menara Amazing</StreetName>
<AdditionalStreetName>Jalan Jalan</AdditionalStreetName>
<CityName>Petaling Jaya</CityName>
<PostalZone>47500</PostalZone>
<ns3:AddressLine>
<Line>20</Line>
</ns3:AddressLine>
<ns3:Country>
<IdentificationCode>MY</IdentificationCode>
</ns3:Country>
</ns3:PostalAddress>
<ns3:PartyTaxScheme>
<CompanyID>SST20201234567</CompanyID>
<ns3:TaxScheme>
<ID>VAT</ID>
</ns3:TaxScheme>
</ns3:PartyTaxScheme>
<ns3:PartyLegalEntity>
<RegistrationName>Amazing HQ</RegistrationName>
<CompanyID>20201234567</CompanyID>
</ns3:PartyLegalEntity>
<ns3:Contact>
<Name>Danny Khoo</Name>
<Telephone>0175622845</Telephone>
<ElectronicMail>[email protected]</ElectronicMail>
</ns3:Contact>
</ns3:Party>
</ns3:AccountingCustomerParty>
<ns3:PayeeParty>
<ns3:PartyIdentification>
<ID schemeID="0230">6715595</ID>
</ns3:PartyIdentification>
<ns3:PartyName>
<Name>Amazing HQ</Name>
</ns3:PartyName>
<ns3:PartyLegalEntity>
<CompanyID>6715595</CompanyID>
</ns3:PartyLegalEntity>
</ns3:PayeeParty>
<ns3:TaxRepresentativeParty>
<ns3:PartyName>
<Name>TTMY Audit</Name>
</ns3:PartyName>
<ns3:PostalAddress>
<StreetName>Unit4.02, Menara Maybank</StreetName>
<AdditionalStreetName>Jalan Plumbum 8</AdditionalStreetName>
<CityName>Shah Alam</CityName>
<PostalZone>47110</PostalZone>
<CountrySubentity>Subentity</CountrySubentity>
<ns3:AddressLine>
<Line>Kepayan</Line>
</ns3:AddressLine>
<ns3:Country>
<IdentificationCode>MY</IdentificationCode>
</ns3:Country>
</ns3:PostalAddress>
<ns3:PartyTaxScheme>
<CompanyID>MY200824324535</CompanyID>
<ns3:TaxScheme>
<ID>VAT</ID>
</ns3:TaxScheme>
</ns3:PartyTaxScheme>
</ns3:TaxRepresentativeParty>
<ns3:Delivery>
<ActualDeliveryDate>2023-11-30</ActualDeliveryDate>
<ns3:DeliveryLocation>
<ID schemeID="0230">7300010000001</ID>
<ns3:Address>
<StreetName>Jalan Amazing 88</StreetName>
<AdditionalStreetName>Pandamaran</AdditionalStreetName>
<CityName>Klang</CityName>
<PostalZone>41200</PostalZone>
<ns3:AddressLine>
<Line>Amazing Sdn Bhd</Line>
</ns3:AddressLine>
<ns3:Country>
<IdentificationCode>MY</IdentificationCode>
</ns3:Country>
</ns3:Address>
</ns3:DeliveryLocation>
<ns3:DeliveryParty>
<ns3:PartyName>
<Name>Monitor ERP</Name>
</ns3:PartyName>
</ns3:DeliveryParty>
</ns3:Delivery>
<ns3:PaymentMeans>
<PaymentMeansCode name="Credit transfer">30</PaymentMeansCode>
<PaymentID>93274234</PaymentID>
<ns3:PayeeFinancialAccount>
<ID>514019459999</ID>
<Name>Ahmad Danial</Name>
<ns3:FinancialInstitutionBranch>
<ID>BIC32409</ID>
</ns3:FinancialInstitutionBranch>
</ns3:PayeeFinancialAccount>
</ns3:PaymentMeans>
<ns3:PaymentTerms>
<Note>60 DAYS</Note>
</ns3:PaymentTerms>
<ns3:AllowanceCharge>
<ChargeIndicator>true</ChargeIndicator>
<AllowanceChargeReasonCode>FC</AllowanceChargeReasonCode>
<AllowanceChargeReason>Delivery service</AllowanceChargeReason>
<MultiplierFactorNumeric>0</MultiplierFactorNumeric>
<Amount currencyID="MYR">0</Amount>
<BaseAmount currencyID="MYR">0</BaseAmount>
<ns3:TaxCategory>
<ID>T</ID>
<Percent>10</Percent>
<ns3:TaxScheme>
<ID>VAT</ID>
</ns3:TaxScheme>
</ns3:TaxCategory>
</ns3:AllowanceCharge>
<ns3:TaxTotal>
<TaxAmount currencyID="MYR">800.00</TaxAmount>
<ns3:TaxSubtotal>
<TaxAmount currencyID="MYR">800.00</TaxAmount>
<ns3:TaxCategory>
<ID>TAX</ID>
<Percent>10</Percent>
<ns3:TaxScheme>
<ID>GST</ID>
</ns3:TaxScheme>
</ns3:TaxCategory>
</ns3:TaxSubtotal>
<ns3:TaxSubtotal>
<TaxableAmount currencyID="MYR">3000.00</TaxableAmount>
<TaxAmount currencyID="MYR">0.00</TaxAmount>
<ns3:TaxCategory>
<ID>E</ID>
<Percent>0</Percent>
<TaxExemptionReasonCode>EEE</TaxExemptionReasonCode>
<TaxExemptionReason>Testing Exempt Tax</TaxExemptionReason>
<ns3:TaxScheme>
<ID>VAT</ID>
</ns3:TaxScheme>
</ns3:TaxCategory>
</ns3:TaxSubtotal>
</ns3:TaxTotal>
<ns3:LegalMonetaryTotal>
<LineExtensionAmount currencyID="MYR">11000.00</LineExtensionAmount>
<AllowanceTotalAmount currencyID="MYR">0</AllowanceTotalAmount>
<ChargeTotalAmount currencyID="MYR">0</ChargeTotalAmount>
<PrepaidAmount currencyID="MYR">0.00</PrepaidAmount>
<PayableRoundingAmount currencyID="MYR">0.00</PayableRoundingAmount>
<PayableAmount currencyID="MYR">11800.00</PayableAmount>
</ns3:LegalMonetaryTotal>
<ns3:InvoiceLine>
<ID>1</ID>
<Note>Please send to gate 7</Note>
<InvoicedQuantity unitCode="EA">50</InvoicedQuantity>
<LineExtensionAmount currencyID="MYR">3000.00</LineExtensionAmount>
<AccountingCost>Marvel</AccountingCost>
<ns3:OrderLineReference>
<LineID>10</LineID>
</ns3:OrderLineReference>
<ns3:DocumentReference>
<ID>Mobile number 1223432432</ID>
<DocumentTypeCode>130</DocumentTypeCode>
</ns3:DocumentReference>
<ns3:Item>
<Name>Marvel Chair AB18 Blue</Name>
<ns3:ClassifiedTaxCategory>
<ID>E</ID>
<Percent>0</Percent>
<TaxExemptionReasonCode>EEE</TaxExemptionReasonCode>
<TaxExemptionReason>Testing Exempt Tax</TaxExemptionReason>
<ns3:TaxScheme>
<ID>GST</ID>
</ns3:TaxScheme>
</ns3:ClassifiedTaxCategory>
</ns3:Item>
<ns3:Price>
<PriceAmount currencyID="MYR">60.00</PriceAmount>
<BaseQuantity unitCode="EA">1</BaseQuantity>
</ns3:Price>
</ns3:InvoiceLine>
<ns3:InvoiceLine>
<ID>2</ID>
<Note>Please send to gate 5</Note>
<InvoicedQuantity unitCode="EA">50</InvoicedQuantity>
<LineExtensionAmount currencyID="MYR">3000.00</LineExtensionAmount>
<AccountingCost>Marvel</AccountingCost>
<ns3:OrderLineReference>
<LineID>20</LineID>
</ns3:OrderLineReference>
<ns3:DocumentReference>
<ID>Mobile number 1223432432</ID>
<DocumentTypeCode>130</DocumentTypeCode>
</ns3:DocumentReference>
<ns3:Item>
<Name>Marvel Chair AB18 Blue</Name>
<ns3:ClassifiedTaxCategory>
<ID>T</ID>
<Percent>10</Percent>
<ns3:TaxScheme>
<ID>VAT</ID>
</ns3:TaxScheme>
</ns3:ClassifiedTaxCategory>
</ns3:Item>
<ns3:Price>
<PriceAmount currencyID="MYR">60.00</PriceAmount>
<BaseQuantity unitCode="EA">1</BaseQuantity>
</ns3:Price>
</ns3:InvoiceLine>
<ns3:InvoiceLine>
<ID>3</ID>
<Note>Please send to gate 5</Note>
<InvoicedQuantity unitCode="EA">100</InvoicedQuantity>
<LineExtensionAmount currencyID="MYR">5000.00</LineExtensionAmount>
<AccountingCost>Marvel</AccountingCost>
<ns3:OrderLineReference>
<LineID>30</LineID>
</ns3:OrderLineReference>
<ns3:DocumentReference>
<ID>Mobile number 1223432432</ID>
<DocumentTypeCode>130</DocumentTypeCode>
</ns3:DocumentReference>
<ns3:Item>
<Name>Marvel Chair AB18 Blue</Name>
<ns3:ClassifiedTaxCategory>
<ID>T</ID>
<Percent>10</Percent>
<ns3:TaxScheme>
<ID>VAT</ID>
</ns3:TaxScheme>
</ns3:ClassifiedTaxCategory>
</ns3:Item>
<ns3:Price>
<PriceAmount currencyID="MYR">50.00</PriceAmount>
<BaseQuantity unitCode="EA">1</BaseQuantity>
</ns3:Price>
</ns3:InvoiceLine>
</ns4:Invoice>
但是一直显示这个错误
[Warning] :1:1: http://www.w3.org/TR/xml-schema-1#SchemaLocation?PINT-jurisdiction-aligned-rules.sch
[Error] :4:81: cvc-elt.1.a: Cannot find the declaration of element 'ns4:Invoice'.
也许您可以使用开源java库https://github.com/phax/phive作为验证引擎和规则https://github.com/phax/phive-rules