2010-06-07 88 views
9

我想根据XSD模式验证XML文件。 XML文件根元素没有任何名称空间或xsi详细信息。它没有属性,所以只有<root>对xml进行Java xsd验证,但没有名称空间

我有我收到没有运气试图从http://www.ibm.com/developerworks/xml/library/x-javaxmlvalidapi.html下面的代码 cvc-elt.1: Cannot find the declaration of element 'root'

SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); 

File schemaFile = new File("schema.xsd"); 

Schema xsdScheme = factory.newSchema(schemaFile); 

Validator validator = xsdScheme.newValidator(); 

Source source = new StreamSource(xmlfile); 

validator.validate(source); 

的XML验证精细与命名空间标题包括等(通过XMLSpy的增加),但我已经想好了XML可以声明名称空间而无需手动编辑源文件?

编辑和解决方案:

public static void validateAgainstXSD(File file) { 

    try { 
     SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); 

     File schemaFile = new File("path/to/xsd"); 

     Schema xsdScheme = factory.newSchema(schemaFile); 

     Validator validator = xsdScheme.newValidator(); 

     SAXSource source = new SAXSource(
       new NamespaceFilter(XMLReaderFactory.createXMLReader()), 
       new InputSource(new FileInputStream(file))); 

     validator.validate(source,null); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

} 

protected static class NamespaceFilter extends XMLFilterImpl { 

    String requiredNamespace = "namespace"; 

    public NamespaceFilter(XMLReader parent) { 
     super(parent); 
    } 

    @Override 
    public void startElement(String arg0, String arg1, String arg2, Attributes arg3) throws SAXException { 
     if(!arg0.equals(requiredNamespace)) 
      arg0 = requiredNamespace; 
     super.startElement(arg0, arg1, arg2, arg3); 
    }  
} 

回答

2

你有两个单独的关注,你需要照顾:

  1. 声明,你的文档使用的命名空间。
  2. 在文件中添加一个xsi:schemaLocation属性,以提示模式所在的提示(!)

您可以安全地跳过第二部分,因为该位置实际上只是一个提示。你不能跳过第一部分。 XML文件中声明的名称空间与模式匹配。重要的是,这样的:

<xml> ... </xml> 

不一样就象这样:

<xml xmlns="urn:foo"> ... </xml> 

所以你需要声明的命名空间中的XML文档中,否则将不符合你的架构和你会得到这个错误。

+1

xml文档是由第三方创建的,它们可能没有添加正确的名称空间,在验证之前,java中是否有方法可以轻松地将此名称空间附加到根xml元素? – 2010-06-08 12:14:12

+2

您可以对此做两件事:1.如果您知道自己在做什么,并且格式非常静态或更好,请使用字符串操作插入它2.创建SAX过滤器以更改命名空间(请参阅http:// www.saxproject.org/filters.html),并将过滤器传递给Validator。我没有尝试过使用Validator对象,但希望它能起作用。 – xcut 2010-06-08 12:43:03

+1

谢谢xcut。我研究了过滤器,它功能强大。对于其他人,请在上面的原始帖子中查看解决方案 – 2010-06-09 15:48:18