phax/ph-schematron

PSSchema made Schematron File with no prefix

wahowaho opened this issue · 9 comments

PSSchema made

image

i want

<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" queryBinding="xslt2">
<sch:ns prefix="xs" uri="http://www.w3.org/2001/XMLSchema"/>

no prefix "sch:";
what shoud i do ,i can not find the method for this. thank you . :)

phax commented

Hello,
this works, but is a little bit tedious ;-)
I created the following snippet that works with the latest version:

    final PSSchema aSchema = /* your job */;

    // Create the XML namespace context
    final MapBasedNamespaceContext aNSCtx = new MapBasedNamespaceContext ();
    aNSCtx.addMapping ("sch", CSchematron.NAMESPACE_SCHEMATRON);
    aNSCtx.addMapping ("xsl", "http://www.w3.org/1999/XSL/Transform");
    // Add all mappings from the PSSchema as well
    for (final PSNS aItem : aSchema.getAllNSs ())
      aNSCtx.addMapping (aItem.getPrefix (), aItem.getUri ());

    // Create the PSWriter settings
    final PSWriterSettings aPSWS = new PSWriterSettings ();
    aPSWS.setXMLWriterSettings (new XMLWriterSettings ().setNamespaceContext (aNSCtx)
                                                        .setPutNamespaceContextPrefixesInRoot (true));

    // Write the Schematron
    new PSWriter (aPSWS).writeToFile (aSchema, new File ("target/test-with-nsprefix.xml"));

WOW,let me try , :), thank you , so surprise that you response so timely . thank you.

it worked。 prefixes are all the same ‘sch’ , but i want <xsl:include href="./functions.xsl" /> ,the prefix is 'xsl',what should i do, :) thank you 。

phax commented

Well I guess, this is because your source Schematron contains the "Schematron-include" and not the "XSLT-include".
Can you paste the relevant parts of the Schematron here? Or are you creating the Schema programmatically?

image
("allow-foreign","true" ) without cache handling , i want to cache the preprocess schamatron ,what shoud i do, thank you.
xsl :
<?xml version="1.0" encoding="UTF-8"?>
<stylesheet
version="2.0"
xmlns:catalog="urn:oasis:names:tc:entity:xmlns:xml:catalog"
xmlns:impl="http://example.org/impl"
xmlns:nf="http://reference.niem.gov/niem/specification/naming-and-design-``rules/4.0/#NDRFunctions"
xmlns:saxon="http://saxon.sf.net/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.w3.org/1999/XSL/Transform">

<param name="xml-catalog" as="document-node()?"/>
<!-- Yields document element of the document containing element $context. -->
<function name="nf:get-document-element" as="element()">
<param name="context" as="element()"/>
<sequence select="root($context)/*"/>
</function>

</stylesheet>

sch:
<?xml version="1.0" encoding="UTF-8"?>
<stylesheet
version="2.0"
xmlns:catalog="urn:oasis:names:tc:entity:xmlns:xml:catalog"
xmlns:impl="http://example.org/impl"
xmlns:nf="http://reference.niem.gov/niem/specification/naming-and-design-``rules/4.0/#NDRFunctions"
xmlns:saxon="http://saxon.sf.net/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.w3.org/1999/XSL/Transform">

<param name="xml-catalog" as="document-node()?"/>
<!-- Yields document element of the document containing element $context. -->
<function name="nf:get-document-element" as="element()">
<param name="context" as="element()"/>
<sequence select="root($context)/*"/>
</function>

`

Hi, I've been thinking about it for a few days, but I can't find a good way to cache files with custom parameters. Reading files takes a long time. Do you have any good Suggestions? Thank you!
I wrote it this way. Execution is fine. but Feel wrong。
import com.helger.commons.collection.impl.CommonsHashMap;
import com.helger.commons.collection.impl.ICommonsMap;
import com.helger.commons.io.IHasInputStream;
import com.helger.commons.io.resource.FileSystemResource;
import com.helger.commons.io.resource.IReadableResource;
import com.helger.schematron.svrl.SVRLMarshaller;
import com.helger.schematron.xslt.*;
import com.helger.xml.EXMLParserFeature;
import com.helger.xml.XMLFactory;
import com.helger.xml.serialize.read.DOMReader;
import com.helger.xml.serialize.read.DOMReaderSettings;
import com.helger.xml.transform.CollectingTransformErrorListener;
import com.helger.xml.transform.TransformSourceFactory;
import org.oclc.purl.dsdl.svrl.SchematronOutputType;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

import javax.annotation.Nonnull;
import javax.xml.transform.Transformer;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

public class Schematron {

private volatile static Schematron schematron;

private static final ICommonsMap<String, SchematronProviderXSLTFromSCH> s_aCache = new CommonsHashMap<>();

private static final String sCacheKey = "schematron_1";
private Schematron()  {
};

public static Schematron getInstance() {
    if (schematron == null){
        synchronized (Schematron.class){
            if (schematron == null){
                schematron = new Schematron();
                File aSchematron = new File("D:\\work\\workSpace\\test\\schematron.sch");
                IReadableResource aRes = new FileSystemResource(aSchematron);
                Map<String,Object> map = new HashMap<>();
                map.put("allow-foreign","true" );
                final CollectingTransformErrorListener aCEH = new CollectingTransformErrorListener ();
                SchematronProviderXSLTFromSCH aPreprocessor = SchematronResourceSCHCache.createSchematronXSLTProvider(aRes,
                        new SCHTransformerCustomizer().setErrorListener(aCEH).setParameters(map)
                                .setLanguageCode("de"));

                s_aCache.put(sCacheKey, aPreprocessor);
            }
        }
    }
    return schematron;
}

/**
 * @param xsdRes
 * @return
 */
public static SchematronOutputType applySchematronValidation(IReadableResource xsdRes) throws Exception {
    SchematronProviderXSLTFromSCH sch =  s_aCache.get(sCacheKey);
    if (sch == null){
        getInstance();
    }
    Transformer transformer = sch.getXSLTTransformer();
    if (transformer == null)
        return null;
    DOMSource var8 = new DOMSource(getAsNode(xsdRes));
    var8.setSystemId(xsdRes.getResourceID());
    Document var4 = XMLFactory.newDocument();
    transformer.transform(var8,new DOMResult(var4));
    final SVRLMarshaller aMarshaller = new SVRLMarshaller ();
    return aMarshaller.read(var4);
}

private static Node getAsNode(@Nonnull IHasInputStream var1) {
    StreamSource var2 = TransformSourceFactory.create(var1);
    InputStream var3 = null;

    try {
        var3 = var2.getInputStream();
    } catch (IllegalStateException var5) {
    }

    if (var3 == null) {
        System.err.println("XML resource " + var1 + " does not exist!");
        return null;
    } else {
        DOMReaderSettings internalCreateDOMReaderSettings = new DOMReaderSettings();
        internalCreateDOMReaderSettings.setFeatureValues(EXMLParserFeature.AVOID_XML_ATTACKS);
        Document var4 = DOMReader.readXMLDOM(var3, internalCreateDOMReaderSettings);
        if (var4 == null) {
            throw new IllegalArgumentException("Failed to read resource " + var1 + " as XML");
        } else {
            System.out.println("Read XML resource " + var1);
            return var4;
        }
    }
}

}

phax commented

I added the method SCHTransformerCustomizer.setForceCacheResult(boolean) for version 5.2.1-SNAPSHOT

thank you very much .:):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)

phax commented

Please close the issue, if that works for you.