验证XSD中的无效属性对XSD
我想弄清楚xml中的任何无效元素或属性。我使用Oxygen XML Editor从xml创建了一个XSD文件。现在我试图解析&使用XSD验证xml,但即使我添加了新属性,我的xml也会解析。以下是代码。现在,即使我将JUNKATTRIBUTE添加到我的xml中,它也会被解析。 有什么建议吗?验证XSD中的无效属性对XSD
我的代码
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>
的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。
UPDATE
正如评论所指出的彼得鲁杜米特,这种有效性不是来自XSD有效性的观点是正确的。名称空间实际上并不是需要进行验证的,但是在不需要名称空间的情况下,应该将模式属性elementFormDefault
设置为“不合格”,以指示模式中的类型可以在没有名称空间限定的情况下引用。
但是,XSD解析器通常会忽略没有名称空间的模式实例,这就是为什么从解析器的角度来看,非名称空间的xml实例总是返回为“有效”(只要其格式良好)。
我很同意你的看法,但是如果OP再次尝试命名空间限定的模式和模式实例,他们会发现解析器现在根据模式验证XML,这是OP所面临的最初问题。 – 2012-01-12 14:59:06
感谢您考虑我的第一条评论。我会尽快将其删除,以保持您的答案清洁。但是,请考虑如果没有模式的目标命名空间(如您在生成的XSD中看到的那样),则此上下文中的elementFormDefault值是无关紧要的。所以我倾向于认为这不是问题,而是一种期望:解析(良构)与验证。我所知道的大多数XML API,通过验证转换的解析始终会成功,因为验证错误在XML解析(格式良好)之外“被观察”。 – 2012-01-12 15:49:40
谢谢休。我无法控制xml。现在,我发现了这个问题。我没有正确捕捉错误,并且设置了Validation = false帮助。 – Mady 2012-01-13 11:00:28
根据您提供您的XML应该得到验证,对所提供的架构代码,但是因为你没有包含定义MySAXHandler
就很难知道你是否是处理错误发生时。
除致命错误外,其他验证错误将通过调用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
这听起来我好像你的期望是不具备XML解析成功,如果它不是XML Schema有效;换句话说,如果XML无效,则parse()应该会引发异常;正确? – 2012-01-12 14:24:24