java - XSD 在使用导入验证 xsd 期间忽略命名空间
问题描述
这个问题我基于简单的例子。我有 2 个 XSD
主要的.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sub="urn:xsd:subXSD"
xmlns="urn:xsd:mainXSD"
targetNamespace="urn:xsd:mainXSD"
elementFormDefault="qualified">
<xs:import namespace="urn:xsd:subXSD" schemaLocation="sub.xsd"/>
<xs:element name="main">
<xs:complexType>
<xs:sequence>
<xs:element name="elementA"/>
<xs:element maxOccurs="unbounded" name="subElement" type="sub:SubType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
子.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="urn:xsd:subXSD"
targetNamespace="urn:xsd:subXSD"
elementFormDefault="qualified">
<xs:complexType name="SubType">
<xs:sequence>
<xs:element name="subA"/>
<xs:element name="subB"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
现在我尝试验证 2 个 xmls
withNamespace.xml
<?xml version="1.0" encoding="UTF-8"?>
<main xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sub="urn:xsd:subXSD"
xmlns="urn:xsd:mainXSD"
xsi:schemaLocation="urn:xsd:mainXSD main.xsd
urn:xsd:subXSD sub.xsd">
<elementA>
Element A content
</elementA>
<subElement>
<sub:subA>sub 1 a</sub:subA>
<sub:subB>sub 1 b</sub:subB>
</subElement>
<subElement>
<sub:subA>sub 2 a</sub:subA>
<sub:subB>sub 2 b</sub:subB>
</subElement>
</main>
没有命名空间.xml
<?xml version="1.0" encoding="UTF-8"?>
<main xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:xsd:mainXSD"
xsi:schemaLocation="urn:xsd:mainXSD main.xsd">
<elementA>
Element A content
</elementA>
<subElement>
<subA>sub 1 a</subA>
<subB>sub 1 b</subB>
</subElement>
<subElement>
<subA>sub 2 a</subA>
<subB>sub 2 b</subB>
</subElement>
</main>
为了验证 xmls,我使用了简单的实现:
import javax.xml.XMLConstants;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import java.io.File;
import java.io.IOException;
public class XSDExample {
public static final String BASE_DIR = "...";
public static void main(String[] args) {
try {
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(new File(BASE_DIR + "main.xsd"));
Validator validator = schema.newValidator();
System.out.println(validate(validator, "withNamespace.xml"));
System.out.println(validate(validator, "withoutNamespace.xml"));
} catch (SAXException | IOException e) {
e.printStackTrace();
}
}
private static String validate(Validator validator, String fileName) throws IOException {
System.out.println(fileName);
try {
validator.reset();
validator.validate(new StreamSource(new File(BASE_DIR + fileName)));
} catch (SAXException e) {
return e.getMessage();
} catch (IOException e) {
throw e;
}
return "Valid";
}
}
执行此代码的输出:
withNamespace.xml
Valid
withoutNamespace.xml
cvc-complex-type.2.4.a: Invalid content was found starting with element 'subA'. One of '{"urn:xsd:subXSD":subA}' is expected.
是否可以创建一个 XSD,它允许我在有和没有导入的 XSD 模式命名空间的情况下验证 XML 文件?或者也许有 javax.xml.validation.Validator 配置来跳过命名空间检查?
解决方案
是否可以创建一个 XSD,它允许我在有和没有导入的 XSD 模式命名空间的情况下验证 XML 文件?
不,没有。
您可以做的是在模式验证之前将两个输入(使用 XSLT)转换为通用形式。将标准化转换作为验证管道的第一步是一项非常有价值的技术,而且还不够广为人知。
推荐阅读
- ios - “NSMutableDictionary”类型的值在 swift 中没有成员“字符串”
- php - pdf2text转换后无法将字符串写入数据库
- c# - 嵌套的 foreach() 迭代混合了目标集合
- amazon-web-services - 如何使用 AWS Route53 从子域重定向到域中的 url
- node.js - 放大发布不断失败,并出现 spawn npm.cmd ENOENT 错误
- database - 该关系满足的更高范式
- c# - C# OpenFileDialog/CommonOpenFileDialog
- linux - 在 Linux Shell 中,如何找出我最常使用的命令以及使用频率?
- google-app-engine - 您可以在 Go 1.12+ 运行时使用 App Engine Standard 上的 `context.Background()` 吗?
- c# - 如何从asp net c#后面的代码清除/重置用户控件中的所有子控件