Avatar billede margitbork Nybegynder
07. december 2011 - 10:38 Der er 1 løsning

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;

    }

   

   

}
Avatar billede margitbork Nybegynder
09. december 2011 - 11:44 #1
HAH - det var bare en mærkelig bug i schema'et - men der er kommet nye versioner fra IT og Telestyrelsen, så de kan nu hentes her:
http://digitaliser.dk/resource/2018566
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester