我可以针对xsd片段验证XML文件吗? 例如,我有一个XML:
<tag1>
<xx>...</xx>
</tag1>
和XSD一样:
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="envTeste">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="tag" minOccurs="1" maxOccurs="1">
<xsd:simpleType>
<xsd:restriction base="xsd:int">
<xsd:totalDigits value="1" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="tag1" minOccurs="1" maxOccurs="1">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:pattern value="^\d{1,15}$"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
............................
我想只使用片段“name = tag1”来验证我的xml。 这是可能的?使用JAXB?
非常感谢。
答案 0 :(得分:1)
不,这对JAXB来说是不可能的,并且我认为任何其他工具都不能在给定当前XML Schema和XML数据的情况下进行这样的部分验证。
首先,您展示的XML不同意XML架构<xsd:element name="tag1"...>>
的部分内容。所以,它无论如何都不会验证。
其次,假设匹配XML Schema代码和XML数据,您可以考虑将XML数据包装到<envTeste>
元素中,但由于缺少<tag>
元素,验证将无法成功。
但是你可以编写一个(正确的,匹配的!)元素<tag1>
作为顶级XML Schema元素,并从<envTeste>
中引用它。然后,可以将包含<tag1>
的XML文档解组,并将XML模式文件传递给unmarshaller。
另一个选择是(一个相当简单的)XSLT从&#34;有趣的&#34;生成XML Schema。元素,将它们安装为顶级元素 - 如果架构不太复杂。 Iffy,但可能是可行的。
答案 1 :(得分:1)
当我第一次删除你的帖子并创建一个新的答案时,我误读了你的帖子:
如果原始模式包含要用于验证的子树,则可以通过XPath表达式(如f.e.)找到子树的顶部节点。如果您不使用命名空间定义,请//@*:name = 'tag1'
或//@name = 'tag1'
。
Node node = (Node)xpath.evaluate(xpathExpression, originSchemaDocument, XPathConstants.NODE);
基本上,您希望以某种方式调用SchemaFactory.newSchema(Source)
来生成可用于验证的架构。因此,最方便的方法是创建DOMSource。
此源可以使用新的Document
生成,您可以使用importNode
将先前提取的子树复制到新的“模式”中。此外,您必须手动或通过从源模式复制向您正在创建的文档添加模式定义,否则您将无法获得有效的模式。
我自己还没有尝试过这种方式但是根据我过去使用这些方法的经验,我认为这可行。
答案 2 :(得分:1)
我认为你遇到的问题是模式的作者选择使tag1成为本地元素声明而不是全局元素声明。如果它是一个全局声明,你可以验证一个独立的tag1元素(人们有时会抱怨XSD的这个特性,但在你的情况下它是你想要的),但由于它是一个本地声明,它只能在上下文中访问其父envTeste元素。此外,envTeste需要存在其他同级元素,因此在验证之前不能简单地将tag1包装在envTeste中。
在这种特殊情况下,您的本地元素声明与其他模式组件没有依赖关系,并且没有涉及名称空间,因此您可以像其他人所建议的那样以文本方式提取它以形成新模式。但在一般情况下,这不起作用。该架构并非旨在按照您尝试使用它的方式使用。
答案 3 :(得分:0)
我以其他方式解决了我的问题。
首先,我使用xmlbeans创建了java对象:
ANT配置:
build.properties
xbean-dest-file = ./lib/sat-beans-1.0.jar # my generated jar
xbean-class-name = org.apache.xmlbeans.impl.tool.XMLBean
xbean-class-path = ./lib/xbean.jar:./lib/jsr173_1.0_api.jar #dependencies
的build.xml
<target name="sat-beans">
<mkdir dir="${xbean-gen}"/>
<mkdir dir="${xbean-classes}"/>
<taskdef name="xmlbean" classname="${xbean-class-name}" classpath="${xbean-class-path}"/>
<xmlbean schema="./xsd/CfeTeste_0006.xsd" classgendir="${xbean-classes}"
srcgendir="${xbean-gen}"
destfile="${xbean-dest-file}"
classpath="${xbean-class-path}" />
</target>
然后我在我的项目中导入了这个jar并进行了如下验证:
public void validate(String xml) {
try {
List<XmlValidationError> errors = new ArrayList<XmlValidationError>();
EnvTesteDocument envTesteDocument = EnvTesteDocument.Factory.parse(xml);
XmlOptions voptions = new XmlOptions();
voptions.setValidateOnSet();
voptions.setErrorListener(errors);
if (envTesteDocument.getEnvTeste().getCFe().validate(voptions)) {
return;
}
for (XmlValidationError error : errors) {
...
}
} catch (XMLInvalidException e) {}
}
感谢所有人!