2

first time dealing with xml, so please be patient. the code below is probably evil in a million ways (I'd be very happy to hear about all of them), but the main problem is of course that it doesn't work :-)

public class Test {

    private static final String JSDL_SCHEMA_URL = "http://schemas.ggf.org/jsdl/2005/11/jsdl";
    private static final String JSDL_POSIX_APPLICATION_SCHEMA_URL = "http://schemas.ggf.org/jsdl/2005/11/jsdl-posix";

    public static void main(String[] args) {
        System.out.println(Test.createJSDLDescription("/bin/echo", "hello world"));
    }    


    private static String createJSDLDescription(String execName, String args) {
        Document jsdlJobDefinitionDocument = getJSDLJobDefinitionDocument();
        String xmlString = null;

        // create the elements
        Element jobDescription = jsdlJobDefinitionDocument.createElement("JobDescription");
        Element application = jsdlJobDefinitionDocument.createElement("Application");
        Element posixApplication = jsdlJobDefinitionDocument.createElementNS(JSDL_POSIX_APPLICATION_SCHEMA_URL, "POSIXApplication");
        Element executable = jsdlJobDefinitionDocument.createElement("Executable");
        executable.setTextContent(execName);
        Element argument = jsdlJobDefinitionDocument.createElement("Argument");
        argument.setTextContent(args);

        //join them into a tree
        posixApplication.appendChild(executable);
        posixApplication.appendChild(argument);
        application.appendChild(posixApplication);
        jobDescription.appendChild(application);
        jsdlJobDefinitionDocument.getDocumentElement().appendChild(jobDescription);

        DOMSource source = new DOMSource(jsdlJobDefinitionDocument);
        validateXML(source);

        try {
            Transformer transformer = TransformerFactory.newInstance().newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            StreamResult result = new StreamResult(new StringWriter());
            transformer.transform(source, result);
            xmlString = result.getWriter().toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return xmlString;
    }

    private static Document getJSDLJobDefinitionDocument() {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = null;
        try {
            builder = factory.newDocumentBuilder();
        } catch (Exception e) {
            e.printStackTrace();
        }
        DOMImplementation domImpl = builder.getDOMImplementation();
        Document theDocument = domImpl.createDocument(JSDL_SCHEMA_URL, "JobDefinition", null);
        return theDocument;
    }

    private static void validateXML(DOMSource source) {
        try {
            URL schemaFile = new URL(JSDL_SCHEMA_URL);
        Sche    maFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
            Schema schema = schemaFactory.newSchema(schemaFile);
            Validator validator = schema.newValidator();
            DOMResult result = new DOMResult();
            validator.validate(source, result);
            System.out.println("is valid");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

it spits out a somewhat odd message:

org.xml.sax.SAXParseException: cvc-complex-type.2.4.a: Invalid content was found starting with element 'JobDescription'. One of '{"http://schemas.ggf.org/jsdl/2005/11/jsdl":JobDescription}' is expected.

Where am I going wrong here?

Thanks a lot

1 Answer 1

3

I think you are missing the namespace on your elements. Rather than calling createElement(), you can try

document.createElementNS(JSDL_SCHEMA_URL, elementName)

If necessary, you may need to use a prefix, e.g.

document.createElementNS(JSDL_SCHEMA_URL, "jsdl:"+elementName)
Sign up to request clarification or add additional context in comments.

2 Comments

blast. it would seem you are correct, sir. Changing createElement to createElementNS solves it. I thought it was implicit... I wonder though if there's a prettier way to do this?
None that I know of - in the DOM namespaces are not inferred from context - each element must define it's namespace. To make it prettier, you could create a small createElement(String name) wrapper method in your class that calls the full createElementNS on the document.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.