Problem med schematron validering
Jeg har en schematron validering som giver mig grå hår:Når jeg vil validere en invoice med disse værdier:
<cbc:MultiplierFactorNumeric>0.200</cbc:MultiplierFactorNumeric>
<cbc:Amount currencyID="DKK">453.20</cbc:Amount>
<cbc:BaseAmount currencyID="DKK">2266.00</cbc:BaseAmount>
fejler den, med denne fejlbesked:
[F-LIB272] Amount must equal BaseAmount * MultiplierFactorNumeric
Jeg har forsøgt med et udvalg af andre værdier - f.eks går det godt med disse værdier:
<cbc:MultiplierFactorNumeric>0.200</cbc:MultiplierFactorNumeric>
<cbc:Amount currencyID="DKK">2000.2</cbc:Amount>
<cbc:BaseAmount currencyID="DKK" >10001.00</cbc:BaseAmount>
Mens disse giver fejl:
<cbc:MultiplierFactorNumeric>0.200</cbc:MultiplierFactorNumeric>
<cbc:Amount currencyID="DKK">200.2</cbc:Amount>
<cbc:BaseAmount currencyID="DKK" >1001.00</cbc:BaseAmount>
Jeg har ikke kunnet finde en logik for hvornår det går galt
Er der nogen der har oplevet tilsvarende ?
Min kode ser således ud:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMXMLParserWrapper;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axiom.om.impl.llom.factory.OMXMLBuilderFactory;
import org.apache.axis2.util.XMLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.ibm.dk.ecs.globals.util.StringUtil;
public class XslTransformUtilImpl {
/**
*/
private static Transformer createTransformer(Element stylesheet) throws TransformerConfigurationException {
Document doc = stylesheet.getOwnerDocument();
Source domSource = new DOMSource(doc);
TransformerFactory transFactory = TransformerFactory.newInstance();
return transFactory.newTransformer(domSource);
}
/**
*/
private static String transformXml(Element document, Transformer transform) throws TransformerException, XMLStreamException {
StreamResult sr = new StreamResult(new ByteArrayOutputStream());
transform.transform(new DOMSource(document.getOwnerDocument()), sr);
String result = sr.getOutputStream().toString();
return result;
}
public void transFormDocuments(byte[] data, StringBuffer writeTo, Properties props) throws Exception{
transFormDocuments(new ByteArrayInputStream(data), writeTo, props);
}
public void transFormDocuments(InputStream dis, StringBuffer writeTo, Properties schemaProperties) throws Exception {
XMLStreamReader parser = XMLInputFactory.newInstance().createXMLStreamReader(dis);
OMXMLParserWrapper builder = OMXMLBuilderFactory.createStAXOMBuilder(OMAbstractFactory.getOMFactory(), parser);
OMElement doc = builder.getDocumentElement();
// doc.build();
Element xmlDocument = XMLUtils.toDOM(doc);
String nameSpace = doc.getNamespace().getNamespaceURI().toLowerCase();
String nameSpaceStr = nameSpace.replaceAll(":", "_");
nameSpaceStr = nameSpaceStr+"_schematron";
String schematronLocation = schemaProperties.getProperty(nameSpaceStr);
writeTo.append("Schematron-validating using schema "+schematronLocation);
writeTo.append(StringUtil.newline);
int cacheminutes = 60;
String cacheValidMinutes = schemaProperties.getProperty("schematron.schema.cache.minutes", "60");
try{
cacheminutes = Integer.parseInt(cacheValidMinutes);
}catch(NumberFormatException nfe){
cacheminutes = 60;
}
Transformer transf = getTransformer(schematronLocation, cacheminutes);
if(transf==null)return; // no schema detected
String result = transformXml(xmlDocument, transf);
System.out.println(schematronLocation);
System.out.println(result);
StringBuffer errMessage = new StringBuffer();
StAXOMBuilder stax = new StAXOMBuilder(new ByteArrayInputStream(result.getBytes()));
OMElement res = stax.getDocumentElement();
boolean hasError = getErrorDetails(res, errMessage);
if(hasError){
throw new Exception(errMessage.toString());
}
}
private void printError(OMElement nxt, StringBuffer errMessage){
errMessage.append(nxt.getFirstChildWithName(new QName("Description")).getText());
errMessage.append(" [xpath:");
errMessage.append(nxt.getFirstChildWithName(new QName("Xpath")).getText());
errMessage.append("]");
errMessage.append(StringUtil.newline);
}
@SuppressWarnings("unchecked")
private boolean getErrorDetails(OMElement res, StringBuffer buf) {
boolean returnval = false;
Iterator<OMElement> ite = res.getChildElements();
while(ite.hasNext()){
OMElement err = ite.next();
if(err.getLocalName().equalsIgnoreCase("error")){
printError(err, buf);
returnval = true;
}
else{
getErrorDetails(err, buf);
}
}
return returnval;
}
private static Map<String, TransformerCache> schemaMap = new HashMap<String, TransformerCache>();
private static Transformer getTransformer(String schemaFileName, int cacheMinutes) throws Exception {
if(StringUtil.isEmpty(schemaFileName))return null;
File schemafile = new File(schemaFileName);
if(!schemafile.exists()){
throw new IllegalArgumentException(schemaFileName+" schema does not exist.");
}
TransformerCache fromMap = schemaMap.get(schemaFileName);
if(fromMap!=null)return fromMap.getTransformer(cacheMinutes);
FileInputStream sis = new FileInputStream(schemafile);
XMLStreamReader parser1 = XMLInputFactory.newInstance().createXMLStreamReader(sis);
OMXMLParserWrapper builder1 = OMXMLBuilderFactory.createStAXOMBuilder(OMAbstractFactory.getOMFactory(), parser1);
OMElement sch = builder1.getDocumentElement();
Element xmlSchema = XMLUtils.toDOM(sch);
try{
sis.close();
}
catch(Exception e){
e.printStackTrace();
}
Transformer trans = createTransformer(xmlSchema);
schemaMap.put(schemaFileName, new TransformerCache(trans));
return trans;
}
}