Title: Sign
Dobrý den,
content handler není nutný pro správnou validaci, používám jej jen proto, abych si dokázal vypsat jméno a cestu k elementu, který je špatně validovaný (zatím jen vypisuji do konzole).

Důležitý je tento řádek:
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Ten Vám zajistí, že se dotáhnou i ostatní XSD.

Nicméně, zde je i ten content handler (je to rozvrtaná verze, právě si s ním hraji).
private static class MyContentHandler extends DefaultHandler {

        private String element = "";
        private int documentNum = 0;
        private List<String> elementPath = new ArrayList<String>();

        @Override
        public void startElement(String uri, String localName, String qName,
                Attributes attributes) throws SAXException {

            if (localName != null && !localName.isEmpty()) {
                element = localName;
            } else {
                element = qName;
            }

            if (StringUtils.equals(element, "Dokument")) {
                documentNum++;
                element += String.valueOf(documentNum);
            }
            elementPath.add(element);           
        }

        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            super.endElement(uri, localName, qName);
            elementPath.remove(elementPath.size() - 1);           
        }

        @Override
        public void warning(SAXParseException exception) throws SAXException {
            printPath();
            System.out.println(element + ": " + exception.getMessage());
        }

        @Override
        public void error(SAXParseException exception) throws SAXException {
            printPath();
            System.out.println(element + ": " + exception.getMessage());
        }

        @Override
        public void fatalError(SAXParseException exception) throws SAXException {
            printPath();
            System.out.println(element + ": " + exception.getMessage());
        }

        public String getElement() {
            return element;
        }

        private void printPath() {
            for (String element : elementPath) {
                System.out.print("/");
                System.out.print(element);
            }
            System.out.println();
        }
    }



GORDIC spol. s r.o. Ing. Vladislav Korecký
vedoucí týmu POR
programátor - analytik

GORDIC - tým POR (Portálová Řešení)
GORDIC spol. s r.o., Erbenova 4, 586 01 Jihlava, Czech Republic
TEL: +420 567 571 491
Dne 4. 2. 2013 16:00, Dušan Rychnovský napsal(a):
Předpokládám, že jeho obsah souvisí s validací. Zbytek kódu se mi zdá napsaný klasicky bez ohledu na importní tagy.

Dušan

Dne 4. února 2013 15:58 Dušan Rychnovský <[email protected]> napsal(a):
> //Creating an instance of our special handler
> final MyContentHandler handler = new MyContentHandler();

Mohl byste prosím přiložit i kód třídy MyContentHandler?

Děkuji za pomoc
Dušan


Dne 4. února 2013 15:36 Vladislav Korecký <[email protected]> napsal(a):

Dobrý den,
řešil jsem stejný problém.
XSD mám v resource, ale je možné použít i XSD z disku. Ostatní XSD leží ve stejné složce jako výchoz XSD.

Java code:
public static void validateXmlFile(File xmlFile) throws ParserConfigurationException, IOException, JAXBException, SAXException {
        //Building a Schema instance
        SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        Source schemaFile = new StreamSource(new File(Validator.class.getResource("/xsd/mets.xsd").getPath()));
        Schema schema = schemaFactory.newSchema(schemaFile);

        //Creating a SAXParser for our input XML
        //First the factory
        final SAXParserFactory factory = SAXParserFactory.newInstance();
        //Must be namespace aware to receive element names
        factory.setNamespaceAware(true);
        //Setting the Schema for validation
        factory.setSchema(schema);
        //Now the parser itself
        final SAXParser parser = factory.newSAXParser();

        //Creating an instance of our special handler
        final MyContentHandler handler = new MyContentHandler();

        //Parsing
        parser.parse(xmlFile, handler);
    }


V XSD mám:
<xsd:schema targetNamespace="http://www.loc.gov/METS/" xmlns="http://www.loc.gov/METS/"
    xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:nsesss="http://www.mvcr.cz/nsesss/v2" elementFormDefault="qualified"
    attributeFormDefault="unqualified">
    <xsd:import namespace="http://www.w3.org/1999/xlink"
        schemaLocation="xlink.xsd" />
    <xsd:import namespace="http://www.mvcr.cz/nsesss/v2"
        schemaLocation="nsesss.xsd" />
    ...


S pozdravem,
Korecký

GORDIC
                                    spol. s r.o. Ing. Vladislav Korecký
vedoucí týmu POR
programátor - analytik

GORDIC - tým POR (Portálová Řešení)
GORDIC spol. s r.o., Erbenova 4, 586 01 Jihlava, Czech Republic
TEL: +420 567 571 491
Dne 4. 2. 2013 14:01, Dušan Rychnovský napsal(a):
Dobrý den,

mám následující problém.

Potřebuji ve své aplikaci validovat XML soubory oproti XSD schématu. Toto schéma je ale rozloženo do několika (cca 10ti) souborů propojených navzájem pomocí tagů include a import.

Podle rad na internetu jsem sestavil níže uvedený kód (prototypu), který ovšem nefunguje dobře.

Kontrolou logů vypisovaných na konzoli se zdá že řešení opravdu prochází tagy include/import (a to průchodem do hloubky), nicméně z neznámých důvodů občas některé z nich přeskočí. Dlouho jsem hledal rozdíly mezi tagy, které se úspěšně zpracují a těmi, které jsou přeskočeny. Nicméně na nic jsem nepřišel.

V konkrétním případě například z těchto tří řádků se první a poslední úspěšně zpracují, zatímco prostřední je ignorován. Všechna schémata existují, jsou dostupná, validní (nicméně to by nemělo mít na chybu vliv, protože resolver vůbec nedostane za úkol tento import řešit).

<import namespace="schemas/src/x20130601" schemaLocation="../../x20130601/Personalnumber.xsd"/>
<import namespace="schemas/src/common/2008/01/03" schemaLocation="../../../contract/x20080103/Contractnumber.xsd"/>
<import namespace="schemas/src/20100504" schemaLocation="../../../system/x20100504/Contractidentification.xsd" />

Díky tomu, že se některé importy nezpracují, pak dostávám výjimky tohoto charakteru:

Exception in thread "main" org.xml.sax.SAXParseException; systemId: file:/z:/--- project path ---/schemas//x20130504/Identification.xsd; lineNumber: 18; columnNumber: 61; src-resolve: Cannot resolve the name 'dat20080103:Contractnumber' to a(n) 'element declaration' component.

Deklarace chybějícího elementu se nachází v přeskočeném XSDčku.

Prosím poraďte, kde hledat chybu, nebo alternativní řešení. 

Předem děkuji za pomoc,
Dušan Rychnovský
------------------
Main.java:

private static final String PROJECT_ROOT_DIR_PATH = "--- project-root-path ---";
private static final String SCHEMAS_ROOT_PATH = "--- schemas root path ---";

private void validate() throws Exception
{
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
builderFactory.setNamespaceAware(true);

DocumentBuilder parser = builderFactory.newDocumentBuilder();

// parse the XML into a document object
Document document = parser.parse(
new File(
PROJECT_ROOT_DIR_PATH +
"src\\test\\resources\\example.xml"
)
);

SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

// associate the schema factory with the resource resolver, which is responsible for resolving the imported XSD's
factory.setResourceResolver(new ResourceResolver(PROJECT_ROOT_DIR_PATH + SCHEMAS_ROOT_PATH));

Schema schema = factory.newSchema(
new File(
PROJECT_ROOT_DIR_PATH +
SCHEMAS_ROOT_PATH +
"--- root-xsd-file-path\\root-schema.xsd ---"
)
);

Validator validator = schema.newValidator();
validator.validate(new DOMSource(document));
}

------------------
ResourceResolver.java:

public class ResourceResolver implements LSResourceResolver 
{
@Override
public LSInput resolveResource(String type, String namespaceURI,
String publicId, String systemId, String baseURI)
{
if (!"http://www.w3.org/2001/XMLSchema".equals(type))
{
throw new IllegalArgumentException(
"Unexpected resource type [" + type + "]."
);
}

if (systemId == null)
{
throw new IllegalArgumentException(
"Unexpected resource system-id [" + systemId + "]."
);
}

System.out.println("base-uri: " + baseURI);
System.out.println("system-id: " + systemId);

URI targetURI = getTargetURI(baseURI, systemId);
System.out.println("target-uri: " + targetURI);

System.out.println("---");

Input input = null;

try {
input = new Input(baseURI, publicId, systemId, targetURI.toURL().openStream());
}
catch (Exception ex)
{
throw new RuntimeException(
"Could not open resource stream - " + ex.getMessage()
);
}

return input;
}

private static URI getTargetURI(String baseURI, String relativePath)
{
URI targetURI = null;

try {
targetURI = (new URI(baseURI)).resolve(relativePath);
}
catch (URISyntaxException ex)
{
throw new RuntimeException(
"Could not resolve target URI - " + ex.getMessage()
);
}

return targetURI;
}
}

------------------
Input.java:

public class Input implements LSInput
{
private BufferedInputStream inputStream;

private String baseURI;
private String publicId;
private String systemId;

public Input(String baseURI, String publicId, String sysId, InputStream input)
{
this.baseURI = baseURI;
this.publicId = publicId;
this.systemId = sysId;
this.inputStream = new BufferedInputStream(input);
}

public String getPublicId()
{
return publicId;
}

public void setPublicId(String publicId)
{
this.publicId = publicId;
}

public String getBaseURI()
{
return baseURI;
}

public InputStream getByteStream()
{
return null;
}

public boolean getCertifiedText()
{
return false;
}

public Reader getCharacterStream()
{
return null;
}

public String getEncoding()
{
return null;
}

public String getStringData()
{
synchronized (inputStream)
{
try {
return IOUtils.toString(inputStream);
}
catch (IOException e) {
e.printStackTrace();
System.out.println("Exception " + e);
return null;
}
}
}

public void setBaseURI(String baseURI) {
}

public void setByteStream(InputStream byteStream) {
}

public void setCertifiedText(boolean certifiedText) {
}

public void setCharacterStream(Reader characterStream) {
}

public void setEncoding(String encoding) {
}

public void setStringData(String stringData) {
}

public String getSystemId() {
return systemId;
}

public void setSystemId(String systemId) {
this.systemId = systemId;
}

public BufferedInputStream getInputStream()
{
return inputStream;
}

public void setInputStream(BufferedInputStream inputStream)
{
this.inputStream = inputStream;
}
}





Odpovedet emailem