From e1881a3891c92fda5a9d6721e5ad7c5a42497f67 Mon Sep 17 00:00:00 2001 From: jstaerk Date: Wed, 11 Nov 2020 21:15:49 +0100 Subject: [PATCH] closes #190 --- History.md | 1 + .../java/org/mustangproject/XMLTools.java | 136 +++++++++++++---- .../ZUGFeRD/ZUGFeRD1PullProvider.java | 138 +++++++++--------- .../ZUGFeRD/ZUGFeRD2PullProvider.java | 8 +- validator/pom.xml | 4 +- .../validator/ValidationResultItem.java | 1 + .../mustangproject/validator/XMLTools.java | 14 -- .../validator/XMLValidator.java | 9 +- .../validator/ZUGFeRDValidator.java | 20 ++- validator/src/test/resources/validV2.xml | 2 +- 10 files changed, 193 insertions(+), 140 deletions(-) delete mode 100644 validator/src/main/java/org/mustangproject/validator/XMLTools.java diff --git a/History.md b/History.md index 3927a8af..c8f90dc0 100644 --- a/History.md +++ b/History.md @@ -51,6 +51,7 @@ switch - contacts also for recipients - absolute and relative allowances and charges on item and document level #135, - support contact fax numbers + - closes #190 BOM not treated correctly on XML input file ### 2.0 still todo - dont show empty tax number field diff --git a/library/src/main/java/org/mustangproject/XMLTools.java b/library/src/main/java/org/mustangproject/XMLTools.java index cf3d6386..402a6dfd 100644 --- a/library/src/main/java/org/mustangproject/XMLTools.java +++ b/library/src/main/java/org/mustangproject/XMLTools.java @@ -1,9 +1,25 @@ package org.mustangproject; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.math.RoundingMode; +import java.util.logging.Level; +import java.util.logging.Logger; -public class XMLTools { +import org.dom4j.io.XMLWriter; +import org.mustangproject.ZUGFeRD.ZUGFeRD2PullProvider; + +public class XMLTools extends XMLWriter { + public String escapeAttributeEntities(String s) { + return super.escapeAttributeEntities(s); + } + + public String escapeElementEntities(String s) { + return super.escapeElementEntities(s); + + } public static String nDigitFormat(BigDecimal value, int scale) { @@ -28,42 +44,98 @@ public class XMLTools { public static String encodeXML(CharSequence s) { - StringBuilder sb = new StringBuilder(); - int len = s.length(); - for (int i=0;i= 0xd800 && c <= 0xdbff && i + 1 < len) { - c = ((c-0xd7c0)<<10) | (s.charAt(++i)&0x3ff); // UTF16 decode - } - if (c < 0x80) { // ASCII range: test most common case first - if (c < 0x20 && (c != '\t' && c != '\r' && c != '\n')) { - // Illegal XML character, even encoded. Skip or substitute - sb.append("�"); // Unicode replacement character - } else { - switch(c) { - case '&': sb.append("&"); break; - case '>': sb.append(">"); break; - case '<': sb.append("<"); break; - // Uncomment next two if encoding for an XML attribute + StringBuilder sb = new StringBuilder(); + int len = s.length(); + for (int i = 0; i < len; i++) { + int c = s.charAt(i); + if (c >= 0xd800 && c <= 0xdbff && i + 1 < len) { + c = ((c - 0xd7c0) << 10) | (s.charAt(++i) & 0x3ff); // UTF16 decode + } + if (c < 0x80) { // ASCII range: test most common case first + if (c < 0x20 && (c != '\t' && c != '\r' && c != '\n')) { + // Illegal XML character, even encoded. Skip or substitute + sb.append("�"); // Unicode replacement character + } else { + switch (c) { + case '&': + sb.append("&"); + break; + case '>': + sb.append(">"); + break; + case '<': + sb.append("<"); + break; + // Uncomment next two if encoding for an XML attribute // case '\'' sb.append("'"); break; // case '\"' sb.append("""); break; - // Uncomment next three if you prefer, but not required + // Uncomment next three if you prefer, but not required // case '\n' sb.append(" "); break; // case '\r' sb.append(" "); break; // case '\t' sb.append(" "); break; - default: sb.append((char)c); - } - } - } else if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff) { - // Illegal XML character, even encoded. Skip or substitute - sb.append("�"); // Unicode replacement character - } else { - sb.append("&#x"); - sb.append(Integer.toHexString(c)); - sb.append(';'); - } - } - return sb.toString(); + default: + sb.append((char) c); + } + } + } else if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff) { + // Illegal XML character, even encoded. Skip or substitute + sb.append("�"); // Unicode replacement character + } else { + sb.append("&#x"); + sb.append(Integer.toHexString(c)); + sb.append(';'); + } + } + return sb.toString(); } + + + /** + * Returns the Byte Order Mark size and thus allows to skips over a BOM + * at the beginning of the given ByteArrayInputStream, if one exists. + * + * @param is the ByteArrayInputStream used + * @throws IOException if can not be read from is + * @see Autodetection of Character Encodings + */ + public static int guessBOMSize(ByteArrayInputStream is) throws IOException { + byte[] pad = new byte[4]; + is.read(pad); + is.reset(); + int test2 = ((pad[0] & 0xFF) << 8) | (pad[1] & 0xFF); + int test3 = ((test2 & 0xFFFF) << 8) | (pad[2] & 0xFF); + int test4 = ((test3 & 0xFFFFFF) << 8) | (pad[3] & 0xFF); + // + if (test4 == 0x0000FEFF || test4 == 0xFFFE0000 || test4 == 0x0000FFFE || test4 == 0xFEFF0000) { + // UCS-4: BOM takes 4 bytes + return 4; + } else if (test3 == 0xEFBBFF) { + // UTF-8: BOM takes 3 bytes + return 3; + } else if (test2 == 0xFEFF || test2 == 0xFFFE) { + // UTF-16: BOM takes 2 bytes + return 2; + } + return 0; + } + + /*** + * removes utf8 byte order marks from byte arrays, in case one is there + * @param zugferdRaw + * @return the byte array without bom + */ + public static byte[] removeBOM(byte[] zugferdRaw) { + byte[] zugferdData; + if ((zugferdRaw[0] == (byte) 0xEF) && (zugferdRaw[1] == (byte) 0xBB) && (zugferdRaw[2] == (byte) 0xBF)) { + // I don't like BOMs, lets remove it + zugferdData = new byte[zugferdRaw.length - 3]; + System.arraycopy(zugferdRaw, 3, zugferdData, 0, zugferdRaw.length - 3); + } else { + zugferdData = zugferdRaw; + } + return zugferdData; + } + + } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD1PullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD1PullProvider.java index 9f954256..2bc7319b 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD1PullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD1PullProvider.java @@ -1,21 +1,23 @@ -/** ********************************************************************** - * +/** + * ********************************************************************* + *

* Copyright 2018 Jochen Staerk - * + *

* Use is subject to license terms. - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at http://www.apache.org/licenses/LICENSE-2.0. - * + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * + *

* See the License for the specific language governing permissions and * limitations under the License. - * - *********************************************************************** */ + *

+ * ********************************************************************** + */ package org.mustangproject.ZUGFeRD; import org.dom4j.Document; @@ -43,7 +45,7 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr protected byte[] zugferdData; private String paymentTermsDescription; SimpleDateFormat zugferdDateFormat = new SimpleDateFormat("yyyyMMdd"); - protected Profile profile=Profiles.getByName("COMFORT",1); + protected Profile profile = Profiles.getByName("COMFORT", 1); /** @@ -52,6 +54,7 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr @Override public void setTest() { } + private String vatFormat(BigDecimal value) { return XMLTools.nDigitFormat(value, 2); } @@ -104,19 +107,19 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr @Override public void generateXML(IExportableTransaction trans) { this.trans = trans; - this.calc=new TransactionCalculator(trans); + this.calc = new TransactionCalculator(trans); - boolean hasDueDate=false; + boolean hasDueDate = false; SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); - String exemptionReason=""; + String exemptionReason = ""; - if (trans.getPaymentTermDescription()!=null) { - paymentTermsDescription=trans.getPaymentTermDescription(); + if (trans.getPaymentTermDescription() != null) { + paymentTermsDescription = trans.getPaymentTermDescription(); } - if (paymentTermsDescription==null) { - paymentTermsDescription= "Zahlbar ohne Abzug bis " + germanDateFormat.format(trans.getDueDate()); - + if (paymentTermsDescription == null) { + paymentTermsDescription = "Zahlbar ohne Abzug bis " + germanDateFormat.format(trans.getDueDate()); + } String senderReg = ""; @@ -135,14 +138,14 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr } String subjectNote = ""; - if (trans.getSubjectNote()!=null) { + if (trans.getSubjectNote() != null) { subjectNote = "\n" + " " - + XMLTools.encodeXML(trans.getSubjectNote())+ "\n" + + XMLTools.encodeXML(trans.getSubjectNote()) + "\n" + "\n"; } - String typecode="380"; - if (trans.getDocumentCode()!=null) { - typecode=trans.getDocumentCode(); + String typecode = "380"; + if (trans.getDocumentCode() != null) { + typecode = trans.getDocumentCode(); } String xml = "\n" @@ -163,12 +166,12 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr + " \n" + " " + XMLTools.encodeXML(trans.getNumber()) + "\n" //$NON-NLS-2$ + " RECHNUNG\n" - + " "+typecode+"\n" + + " " + typecode + "\n" + " " + zugferdDateFormat.format(trans.getIssueDate()) + "\n" // date - // format - // was - // 20130605 + // format + // was + // 20130605 + subjectNote + rebateAgreement + senderReg @@ -181,14 +184,14 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr } xml = xml + " \n"; - xml+= getTradePartyAsXML(trans.getSender(), true); - xml+= " \n" + xml += getTradePartyAsXML(trans.getSender(), true); + xml += " \n" + " \n"; // + " GE2020211\n" // + " 4000001987658\n" - xml+= getTradePartyAsXML(trans.getRecipient(), false); - if ((trans.getOwnVATID()!=null)&&(trans.getOwnOrganisationName()!=null)) { + xml += getTradePartyAsXML(trans.getRecipient(), false); + if ((trans.getOwnVATID() != null) && (trans.getOwnOrganisationName() != null)) { xml = xml + " \n" + " " + XMLTools.encodeXML(trans.getOwnVATID()) + "\n" + " "; @@ -196,21 +199,21 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr xml += " \n"; - if (trans.getBuyerOrderReferencedDocumentID()!=null) { + if (trans.getBuyerOrderReferencedDocumentID() != null) { xml = xml + " \n" + " " + XMLTools.encodeXML(trans.getBuyerOrderReferencedDocumentID()) + "\n" + " \n"; } - xml = xml + " \n" - + " \n" ; - if (this.trans.getDeliveryAddress()!=null) { - xml += ""+ - getTradePartyAsXML(this.trans.getDeliveryAddress(), false)+ + xml = xml + " \n" + + " \n"; + if (this.trans.getDeliveryAddress() != null) { + xml += "" + + getTradePartyAsXML(this.trans.getDeliveryAddress(), false) + ""; } - xml+= " \n" + xml += " \n" + " "; if (trans.getDeliveryDate() != null) { @@ -231,21 +234,21 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr + " " + XMLTools.encodeXML(trans.getNumber()) + "\n" //$NON-NLS-2$ + " " + trans.getCurrency() + "\n"; - if (trans.getTradeSettlementPayment()!=null) { + if (trans.getTradeSettlementPayment() != null) { for (IZUGFeRDTradeSettlementPayment payment : trans.getTradeSettlementPayment()) { - if(payment!=null) { - hasDueDate=true; - xml+=payment.getSettlementXML(); + if (payment != null) { + hasDueDate = true; + xml += payment.getSettlementXML(); } } } - if (trans.getTradeSettlement()!=null) { + if (trans.getTradeSettlement() != null) { for (IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) { - if(payment!=null) { + if (payment != null) { if (payment instanceof IZUGFeRDTradeSettlementPayment) { - hasDueDate=true; + hasDueDate = true; } - xml+=payment.getSettlementXML(); + xml += payment.getSettlementXML(); } } } @@ -260,7 +263,7 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr + " VAT\n" + exemptionReason + " " + currencyFormat(amount.getBasis()) + "\n" // currencyID=\"EUR\" - + " "+amount.getCategoryCode()+"\n" + + " " + amount.getCategoryCode() + "\n" + " " + vatFormat(currentTaxPercent) + "\n" + " \n"; //$NON-NLS-2$ @@ -279,7 +282,7 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr } } - if (hasDueDate && (trans.getDueDate()!=null)) { + if (hasDueDate && (trans.getDueDate() != null)) { xml = xml + " " // $NON-NLS-2$ + zugferdDateFormat.format(trans.getDueDate()) + "\n";// 20130704 @@ -291,7 +294,7 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr } xml = xml + " \n" - + " " + currencyFormat(calc.getTotal()) + "\n" //$NON-NLS-2$ + + " " + currencyFormat(calc.getTotal()) + "\n" //$NON-NLS-2$ // currencyID=\"EUR\" + " 0.00\n" // currencyID=\"EUR\" + " 0.00\n" // @@ -317,8 +320,8 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr int lineID = 0; for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { lineID++; - if (currentItem.getProduct().getTaxExemptionReason() != null) { - exemptionReason="" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + ""; + if (currentItem.getProduct().getTaxExemptionReason() != null) { + exemptionReason = "" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + ""; } @@ -329,10 +332,10 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr + " \n" + " \n" + " \n" - + " " + priceFormat(lc.getPriceGross()) + + " " + priceFormat(lc.getPriceGross()) + "\n" + " " + quantityFormat(currentItem.getBasisQuantity()) +"\n" + + "\">" + quantityFormat(currentItem.getBasisQuantity()) + "\n" // + " \n" // + " false\n" // + " 0.6667\n" @@ -340,10 +343,10 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr // + " \n" + " \n" + " \n" - + " " + priceFormat(currentItem.getPrice()) + + " " + priceFormat(currentItem.getPrice()) + "\n" + " " + quantityFormat(currentItem.getBasisQuantity()) +"\n" + + "\">" + quantityFormat(currentItem.getBasisQuantity()) + "\n" + " \n" + " \n" @@ -356,21 +359,21 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr + " \n" + " VAT\n" + exemptionReason - + " "+currentItem.getProduct().getTaxCategoryCode()+"\n" + + " " + currentItem.getProduct().getTaxCategoryCode() + "\n" + " " + vatFormat(currentItem.getProduct().getVATPercent()) + "\n" + " \n" + " \n" - + " " + currencyFormat(lc.getItemTotalNetAmount()) + + " " + currencyFormat(lc.getItemTotalNetAmount()) + "\n" + " \n"; - if (currentItem.getAdditionalReferencedDocumentID()!=null) { - xml=xml + " "+currentItem.getAdditionalReferencedDocumentID()+"130\n"; + if (currentItem.getAdditionalReferencedDocumentID() != null) { + xml = xml + " " + currentItem.getAdditionalReferencedDocumentID() + "130\n"; - } - xml=xml + " \n" - + " \n"; + } + xml = xml + " \n" + + " \n"; // + " 4012345001235\n" if (currentItem.getProduct().getSellerAssignedID() != null) { xml = xml + " " @@ -404,14 +407,7 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr byte[] zugferdRaw; try { zugferdRaw = xml.getBytes("UTF-8"); - - if ((zugferdRaw[0] == (byte) 0xEF) && (zugferdRaw[1] == (byte) 0xBB) && (zugferdRaw[2] == (byte) 0xBF)) { - // I don't like BOMs, lets remove it - zugferdData = new byte[zugferdRaw.length - 3]; - System.arraycopy(zugferdRaw, 3, zugferdData, 0, zugferdRaw.length - 3); - } else { - zugferdData = zugferdRaw; - } + zugferdData = XMLTools.removeBOM(zugferdRaw); } catch (UnsupportedEncodingException e) { Logger.getLogger(ZUGFeRD1PullProvider.class.getName()).log(Level.SEVERE, null, e); } @@ -419,7 +415,7 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr @Override public void setProfile(Profile p) { - profile=p; + profile = p; } private String buildPaymentTermsXml() { @@ -453,7 +449,7 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr paymentTermsXml += ""; paymentTermsXml += "" + zugferdDateFormat.format(baseDate) + ""; paymentTermsXml += ""; - + paymentTermsXml += "" + discountTerms.getBasePeriodMeasure() + ""; } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java index 4895122f..c5e4f294 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java @@ -615,13 +615,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { try { zugferdRaw = xml.getBytes("UTF-8"); - if ((zugferdRaw[0] == (byte) 0xEF) && (zugferdRaw[1] == (byte) 0xBB) && (zugferdRaw[2] == (byte) 0xBF)) { - // I don't like BOMs, lets remove it - zugferdData = new byte[zugferdRaw.length - 3]; - System.arraycopy(zugferdRaw, 3, zugferdData, 0, zugferdRaw.length - 3); - } else { - zugferdData = zugferdRaw; - } + zugferdData=XMLTools.removeBOM(zugferdRaw); } catch (UnsupportedEncodingException e) { Logger.getLogger(ZUGFeRD2PullProvider.class.getName()).log(Level.SEVERE, null, e); } diff --git a/validator/pom.xml b/validator/pom.xml index 77781d5a..a7f839e3 100644 --- a/validator/pom.xml +++ b/validator/pom.xml @@ -161,8 +161,8 @@ - 1.7 - 1.7 + 8 + 8 diff --git a/validator/src/main/java/org/mustangproject/validator/ValidationResultItem.java b/validator/src/main/java/org/mustangproject/validator/ValidationResultItem.java index 27a4ca67..1f7d1343 100644 --- a/validator/src/main/java/org/mustangproject/validator/ValidationResultItem.java +++ b/validator/src/main/java/org/mustangproject/validator/ValidationResultItem.java @@ -1,5 +1,6 @@ package org.mustangproject.validator; +import org.mustangproject.XMLTools; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/validator/src/main/java/org/mustangproject/validator/XMLTools.java b/validator/src/main/java/org/mustangproject/validator/XMLTools.java deleted file mode 100644 index 13eb810f..00000000 --- a/validator/src/main/java/org/mustangproject/validator/XMLTools.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.mustangproject.validator; - -import org.dom4j.io.XMLWriter; - -public class XMLTools extends XMLWriter { - public String escapeAttributeEntities(String s) { - return super.escapeAttributeEntities(s); - } - public String escapeElementEntities(String s) { - return super.escapeElementEntities(s); - - } - -} diff --git a/validator/src/main/java/org/mustangproject/validator/XMLValidator.java b/validator/src/main/java/org/mustangproject/validator/XMLValidator.java index 8b804425..5ac6e220 100644 --- a/validator/src/main/java/org/mustangproject/validator/XMLValidator.java +++ b/validator/src/main/java/org/mustangproject/validator/XMLValidator.java @@ -18,6 +18,7 @@ import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathFactory; +import org.mustangproject.XMLTools; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; @@ -61,7 +62,7 @@ public class XMLValidator extends Validator { // file existence must have been checked before try { - zfXML = new String(Files.readAllBytes(Paths.get(name))); + zfXML = new String(XMLTools.removeBOM(Files.readAllBytes(Paths.get(name)))); } catch (IOException e) { ValidationResultItem vri = new ValidationResultItem(ESeverity.exception, e.getMessage()).setSection(9) @@ -112,8 +113,6 @@ public class XMLValidator extends Validator { failedRules = 0; - ByteArrayInputStream xmlByteInputStream = new ByteArrayInputStream(zfXML.getBytes(StandardCharsets.UTF_8)); - if (zfXML.isEmpty()) { ValidationResultItem res = new ValidationResultItem(ESeverity.exception, "XML data not found in " + filename @@ -145,8 +144,8 @@ public class XMLValidator extends Validator { // document.getElementsByTagNameNS("*",... DocumentBuilder db = dbf.newDocumentBuilder(); - - Document doc = db.parse(xmlByteInputStream); + InputSource is = new InputSource(new StringReader(zfXML)); + Document doc = db.parse(is); Element root = doc.getDocumentElement(); diff --git a/validator/src/main/java/org/mustangproject/validator/ZUGFeRDValidator.java b/validator/src/main/java/org/mustangproject/validator/ZUGFeRDValidator.java index 69cef429..e8d976eb 100644 --- a/validator/src/main/java/org/mustangproject/validator/ZUGFeRDValidator.java +++ b/validator/src/main/java/org/mustangproject/validator/ZUGFeRDValidator.java @@ -1,11 +1,7 @@ package org.mustangproject.validator; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.StringWriter; +import java.io.*; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.security.MessageDigest; @@ -22,11 +18,13 @@ import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.io.OutputFormat; import org.dom4j.io.XMLWriter; +import org.mustangproject.XMLTools; import org.riversun.bigdoc.bin.BigFileSearcher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.xml.sax.InputSource; import org.xml.sax.SAXParseException; //abstract class @@ -165,8 +163,12 @@ public class ZUGFeRDValidator { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); - - Document doc = db.parse(file); + + byte[] content=Files.readAllBytes(file.toPath()); + content= XMLTools.removeBOM(content); + String s=new String(content); + InputSource is = new InputSource(new StringReader(s)); + Document doc = db.parse(is); Element root = doc.getDocumentElement(); isXML=true;//no exception so far @@ -176,6 +178,8 @@ public class ZUGFeRDValidator { // probably no xml file, sth like SAXParseException content not allowed in prolog // ignore isXML is already false // in the tests, this may error-out anyway + //ex.printStackTrace(); + } if (isXML) { pdfValidity = true; diff --git a/validator/src/test/resources/validV2.xml b/validator/src/test/resources/validV2.xml index 3381bee2..3d129ea2 100644 --- a/validator/src/test/resources/validV2.xml +++ b/validator/src/test/resources/validV2.xml @@ -1,4 +1,4 @@ - +