根据XSD验证XML中的无效属性

时间:2012-01-12 08:47:38

标签: java xml xsd saxparser

我想找出xml中的任何无效元素或属性。我使用Oxygen XML Editor从xml创建了一个XSD文件。现在我正在尝试解析&使用XSD验证xml,但即使添加新属性,我的xml也会解析。下面是代码。现在即使我将JUNKATTRIBUTE添加到我的xml中,它也会被解析。 有什么建议吗?

我的代码

public static boolean validatehelp(String helpData, helpReport helpReport) {

    SAXParserFactory spf = SAXParserFactory.newInstance();
    SAXParser parser = null;
    spf.setNamespaceAware(true);
    spf.setValidating(true);

    FileReader fileReader = null;
    try {
         SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
         fileReader =  new FileReader("help_xsd.xsd");

         spf.setSchema(sf.newSchema(new SAXSource(new InputSource(fileReader))));
         //spf.setSchema(sf.newSchema(new Source[] {new StreamSource("help_xsd.xsd")}));



        parser = spf.newSAXParser();

        MySAXHandler handler = new MySAXHandler(configReport); 

        parser.parse(new InputSource(new StringReader(helpData)), handler);
        return true;
    }

我的xml

<Help date="2020-06-24">
<product
id="en_US_SAN_15.0"
label="orange_16.0"
ProductName="orange 16.0 "
productName="orange 16.0 Pre"
productVersion="15.0"
baseUrl="http://help.stage.xyz.com/"
path="Help/en_US/"
ionId="orange_product_xyzlr"
ionCommentingAllowed="yes"
ionSiteArea="help"
ionRatingAllowed="yes"
ionRatingType="thumbs"
searchOptions="Community|xyz"
searchDefault="Community"
searchxyzRefinement="site=orange_V2_all"
="yes"
/>
<package
id="en_US_SAN_15.0_Using"
label="orange_16.0"
path="SAN/orange/15.0/Using"
description="SAN 15.0"
contextSensitivity="yes"
downloadContent="client.orange_V2_Using_en-us.zip"
downloadContentDefault="yes"
downloadPdf="orange_V4_help.pdf"
JUNKATTRIBUTE="JUNK"
/>
</Help>

我的XSD

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
  <xs:element name="Help">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="product"/>
        <xs:element ref="package"/>
      </xs:sequence>
      <xs:attribute name="appId" />
      <xs:attribute name="date"  type="xs:date"/>
      <xs:attribute name="locale" type="xs:NCName"/>
      <xs:attribute name="pubId" />
      <xs:attribute name="version"  type="xs:decimal"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="product">
    <xs:complexType>
      <xs:attribute name="baseUrl" type="xs:anyURI"/>
      <xs:attribute name="helpServiceUrl" type="xs:anyURI"/>
      <xs:attribute name="id" type="xs:NCName"/>
      <xs:attribute name="ionCommentingAllowed"  type="xs:NCName"/>
      <xs:attribute name="ionId"  type="xs:NCName"/>
      <xs:attribute name="ionRatingAllowed"  type="xs:NCName"/>
      <xs:attribute name="ionRatingType"  type="xs:NCName"/>
      <xs:attribute name="ionSiteArea"  type="xs:NCName"/>
      <xs:attribute name="label" />
      <xs:attribute name="multidomain"  type="xs:NCName"/>
      <xs:attribute name="path" />
      <xs:attribute name="productName"  type="xs:NCName"/>
      <xs:attribute name="productVersion"  type="xs:NCName"/>
      <xs:attribute name="searchxyzRefinement" />
      <xs:attribute name="searchBlueprintRefinement"  type="xs:NCName"/>
      <xs:attribute name="searchCommunityRefinement"  type="xs:NCName"/>
      <xs:attribute name="searchDefault"  type="xs:NCName"/>
      <xs:attribute name="searchOptions" />
    </xs:complexType>
  </xs:element>
  <xs:element name="package">
    <xs:complexType>
      <xs:attribute name="alias" />
      <xs:attribute name="baseUrl"  type="xs:anyURI"/>
      <xs:attribute name="contextSensitivity"  type="xs:NCName"/>
      <xs:attribute name="deprecated"  type="xs:NCName"/>
      <xs:attribute name="description" />
      <xs:attribute name="downloadContent" />
      <xs:attribute name="downloadContentDefault"  type="xs:NCName"/>
      <xs:attribute name="downloadPdf"  type="xs:NCName"/>
      <xs:attribute name="helpmapPath"  type="xs:anyURI"/>
      <xs:attribute name="id"  type="xs:NCName"/>
      <xs:attribute name="label" />
      <xs:attribute name="packageGenerator"  type="xs:NCName"/>
      <xs:attribute name="path" />
      <xs:attribute name="urlParams" />
    </xs:complexType>
  </xs:element>
</xs:schema>

2 个答案:

答案 0 :(得分:1)

如果符合以下条件,则XML文件有效:

  • 结构良好
  • 它符合与之关联的任何已定义的架构类型。

在您的情况下,xml文档格式正确,并且没有与之关联的架构。因此它是有效的。

如果要将xml与定义的类型相关联,则需要使用命名空间。

您的架构声明:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="myNamespaceHere" xmlns="myNamespaceHere">
...
</xs:schema>

你的xml实例:

<Help date="2020-06-24" xmlns="myNamespaceHere">
...
</Help>

现在,当您验证它时,您的解析器将知道对XSD进行验证。

<强>更新

正如Petru在评论中指出的那样,从 XSD有效性的角度来看,这种有效性是不正确的。实际上并不需要命名空间进行验证,但是在不需要命名空间的情况下,应将架构属性elementFormDefault设置为“不合格”,以指示可以在没有命名空间限定的情况下引用架构中的类型。

然而,XSD解析器通常忽略没有命名空间的模式实例,这就是为什么从解析器的角度来看,非命名空间的xml实例总是返回为“有效”(只要它的格式正确)。

答案 1 :(得分:0)

根据您提供的代码,您的XML应该根据提供的架构进行验证,但是由于您没有包含MySAXHandler的定义,因此很难知道您是否处理< / em>发生时的错误。

除致命错误外,还会通过DefaultHandler.error()调用SAXParseException方法报告其他验证错误。如果要处理验证错误,则需要实现该方法。类似的东西:

class MyHandler extends DefaultHandler {
    public void error(SAXParseException exception) throws SAXParseException {
        throw exception;
    }
}

使用此处理程序定义(以及其余代码),您应该看到parse抛出SAXParseException验证异常。

有关ErrorHandler界面的详细信息,请参阅:http://docs.oracle.com/javase/6/docs/api/org/xml/sax/ErrorHandler.html