针对包含 xsd:import without location 的 XSD 验证 XML

Posted

技术标签:

【中文标题】针对包含 xsd:import without location 的 XSD 验证 XML【英文标题】:Validating XML against XSD containing xsd:import without location 【发布时间】:2013-09-02 19:36:43 【问题描述】:

如何根据 XSD Schema 验证 XML,其中包含没有 schema-location 的导入?

XSD 的片段:

<xs:schema xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types
    xmlns:tns="http://schemas.microsoft.com/exchange/services/2006/types"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://schemas.microsoft.com/exchange/services/2006/types"
    elementFormDefault="qualified" version="Exchange2010_SP2" id="types">
    <xs:import namespace="http://www.w3.org/XML/1998/namespace"/>
...

已经阅读并尝试过:

This one 和 this too... 不成功。

无法从架构中删除此导入,因为它包含 xml:lang 属性的引用。

variant 1 ResourceResolver 中用 systemId = null

触发的 resolveResource 方法
public class ResourceResolver  implements LSResourceResolver 

    public LSInput resolveResource(String type, String namespaceURI,
            String publicId, String systemId, String baseURI) 

      //Some implementation

      return new Input(publicId, systemId, resourceAsStream);

variant 2 中尝试这样:

SchemaFactory sFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        //sFactory.setResourceResolver(new ResourceResolver());
        Schema schema = sFactory.newSchema(new Source[] 
            new StreamSource("http://www.w3.org/XML/1998/namespace"),
            new StreamSource(MailGateMQBinding.class.getResourceAsStream("/types.xsd")),
        );
validator = messageSchema.newValidator();
            source = new DOMSource(inDocBody);
            validator.validate(source);

但有一个例外: 没有new StreamSource("http://www.w3.org/XML/1998/namespace") org.xml.sax.SAXParseException:src-resolve:无法将名称“xml:lang”解析为(n)“属性声明”。

还有这个new StreamSource("http://www.w3.org/XML/1998/namespace") org.xml.sax.SAXParseException: s4s-elt-character: 'xs:appinfo' 和 'xs:documentation' 以外的架构元素中不允许使用非空白字符。看到“xml:”命名空间'。

任何帮助将不胜感激。

【问题讨论】:

使用 Saxon XSD 处理器,此命名空间的知识是内置的,因此您无需提供位置。我猜你正在使用 Apache Xerces 处理器? @MichaelKay :是的,我的 EE 容器 IBM WebSphere Application Server 使用 Apache Xerces 处理器(也许,由 IBM 修改)。 【参考方案1】:

http://www.w3.org/XML/1998/namespace 命名空间的 XML 架构位于此处: https://www.w3.org/2009/01/xml.xsd

因此,您只需在架构中的 &lt;xs:import&gt; 中指定其位置:

<xs:schema xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types
    xmlns:tns="http://schemas.microsoft.com/exchange/services/2006/types"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://schemas.microsoft.com/exchange/services/2006/types"
    elementFormDefault="qualified" version="Exchange2010_SP2" id="types">

    <xs:import namespace="http://www.w3.org/XML/1998/namespace" 
               schemaLocation="https://www.w3.org/2009/01/xml.xsd"/>
...

这可行,但请注意,W3C 不喜欢该文件的大量流量:http://www.w3.org/2001/xml.xsd。因此,他们人为地延迟了对它的访问。

许多软件都拥有此类架构的本地副本。 (这就是未指定架构位置的原因。架构软件通常从其资源中加载它)。

您也可以将其复制到您的计算机并指定该副本的 URL。

另一种方法是使用 XML 目录,像这样 (catalog.xml):

<?xml version="1.0"?>
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
  <!-- 
    This will redirect the namespace URI to the local schema file,
    which should be found in the same directory as the catalog.xml
  -->
  <uri name="http://www.w3.org/XML/1998/namespace" uri="xml.xsd"/>
</catalog>

但是您必须以某种方式将该目录文件传递给您的架构处理器软件 (如果它支持 XML 目录)

【讨论】:

非常感谢!这就是诀窍。使用 xml.xsd 项目的本地副本可以在两种变体中使用。 新的 schemaLocation 不再是 http://www.w3.org/2001/xml.xsd,现在新的 schemaLocation 在 https://www.w3.org/2009/01/xml.xsd【参考方案2】:

只需删除:

<!DOCTYPE xs:schema PUBLIC "-//W3C//DTD XMLSCHEMA 200102//EN" "XMLSchema.dtd">

来自 xml.xsd

然后改变

<xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/>

如果是同样的错误,它会很有用。

【讨论】:

以上是关于针对包含 xsd:import without location 的 XSD 验证 XML的主要内容,如果未能解决你的问题,请参考以下文章

如何查找不包含给定字符串模式的文件?

leetcode -- Algorithms -- 3_ Longest Substring Without Repeating Characters

虚拟化从VirtIO without Virt到DPU

[刷题] LeetCode 3 Longest Substring Without Repeating Character

Leetcode 3. Longest Substring Without Repeating Characters(python)

pandas使用notna函数all函数sum函数计算dataframe中不包含缺失值的数据行的个数(number of rows without missing values)