2010-05-09 3 views
2

xml을 처음 다루기 때문에 기다려주십시오. 아래의 코드는 (I에 대한 그들 모두를 듣고 매우 행복 할 것) 만 가지 방법으로 아마 악이지만, 가장 큰 문제는Java에서 XML 유효성 검사 - 이것이 실패하는 이유는 무엇입니까?

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(); 
     } 
    } 

} 

그것을 뱉어 :-) 작동하지 않습니다 물론이다 다소 이상한 메시지가 나온다.

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. 

여기서 나는 잘못 가고 있니?

고마워요

답변

3

여러분의 요소에 네임 스페이스가 누락되었다고 생각합니다. 당신은, 예를 접두사를 사용해야 할 수도 있습니다 필요한 경우 오히려 createElement()를 호출하는 대신

document.createElementNS(JSDL_SCHEMA_URL, elementName) 

을 시도 할 수 있습니다

document.createElementNS(JSDL_SCHEMA_URL, "jsdl:"+elementName) 
+0

폭발. 네가 옳은 것 같아. createElement를 createElement로 변경하면 해결됩니다. 나는 그것이 암시 적이라고 생각했습니다 ... 이것을 할 수있는 더 좋은 방법이있다면 궁금합니다. –

+0

DOM 이름 공간이 컨텍스트에서 유추되지 않는다는 것을 알지 못했습니다. 각 요소는 네임 스페이스를 정의해야합니다. 그것을 더 좋게 만들려면, 클래스에서 createElementNS (String name) 래퍼 메서드를 작게 만들어 문서에서 전체 createElementNS를 호출하면됩니다. – mdma

관련 문제