微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用通用限制模式验证所有元素的 XSD 模式:例如允许的字符

如何解决使用通用限制模式验证所有元素的 XSD 模式:例如允许的字符

我有许多复杂的 XSD 文件用于验证传入的 XML。这些 XSD 是标准的,会不时更新。

最重要的是,有一项业务限制规定,任何元素/属性中只允许使用特定的拉丁字符、数字和符号子集。

我的想法不是去每个 XSD 并为每个 simpleType 添加模式限制(由于多种原因,这是不可能的),我的想法是创建一个通用 XSD,在特定 XSD 之前用作一般验证将应用验证。

但是,我无法找到一种方法对可变元素集应用相同的限制,无论它们在何处声明以及声明的深度如何。

为了给您一个想法,我想到使用 xsd:any 并像这样应用相同的 simpleType

<!-- XSD for allowable characters -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">

    <xs:element name="AppHdr" type="AnyRoot"/>

    <xs:simpleType name="AnyElement">
        <xs:restriction base="xs:string">
            <xs:pattern value="[A-Za-z0-9]*"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:complexType name="AnyRoot">
        <xs:sequence>
            <xs:any namespace="##any" processContents="skip"
                    minOccurs="0" maxOccurs="unbounded"
                    type="AnyElement"/>
        </xs:sequence>
    </xs:complexType>

</xs:schema>

不幸的是,type 中不允许使用 xs:any 属性,因此这是无效的。也许这与 xs:group 的组合可以解决问题?

搜索任何替代方法但没有运气,我发现所有类似的方法都涉及更改具有已知名称和位置的原始 XSD 中的特定元素。这对我来说不行

起初,我认为这似乎是微不足道的常见情况,但结果证明这是一种罕见的情况。

如果有人能对此有所了解,我将不胜感激。谢谢!

[编辑]:

我最终决定采用另一条路径而不是 XSD,我使用 XSL 来过滤无效字符并在找到后返回报告。

<?xml version="1.0" encoding="UTF-8"?>
<!-- XSL for allowable characters: Andreas Gounaris,2021 -->
<xsl:stylesheet version="2.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:devdom="http://example.com/xfunctions/"
                extension-element-prefixes="devdom">
    <xsl:output method="text" media-type="text/plain" indent="no" omit-xml-declaration="yes" encoding="UTF-8"/>

    <!-- Matching document root -->
    <xsl:template match="/">
        <xsl:apply-templates select="*" mode="verify"/>
    </xsl:template>

    <!-- Remove whitespace between nodes -->
    <xsl:template match="text()[not(normalize-space())]" mode="verify"/>

    <xsl:template match="*" mode="verify">
        <xsl:apply-templates select="@* | node()" mode="verify"/>
    </xsl:template>

    <!-- Matching attribute and text nodes -->
    <xsl:template match="@* | text()" mode="verify">
        <xsl:variable name="invalidContent" select="devdom:exslt_verify_mx_disclosure_chars(.)"/>
        <xsl:if test="$invalidContent">
            <xsl:value-of select="concat(name(parent::*),': ',$invalidContent)"/>
            <xsl:value-of select="'|-|'"/>
        </xsl:if>
    </xsl:template>

</xsl:stylesheet>

转换器遍历所有属性和文本节点,并以当前节点作为参数调用 XSLT 外部函数 exslt_verify_mx_disclosure_chars。 该函数匹配正则表达式中任何但有效的字符。

在这个例子中,我返回一个以字符串分隔的文本文件“|-|”但它也可以是 XML。

解决方法

使用 XPath 或 XSLT 2 或 3 的 Schematron 可能类似于

Wanted but not invoked:
activityMainViewModel.getCdfwData();
-> at cerence.assistant.reference.app.ui.activity.main.ActivityMainViewModel.getCdfwData
,

如果这是混合内容,那么您绝对不能这样做(没有 XSD 1.1 断言)- 没有办法限制出现在混合内容中的文本。

对于简单类型,您可以使用适当的模式限制使所有(基于字符串的)简单类型派生自 xs:string 的子类型,但如果重构过多,那么您将拥有寻找另一种方式。

如果您要进行独立于 XSD 验证的单独验证通过,那么 XSD 似乎不是执行此操作的正确技术。如果您在 Java 世界中,我很想使用放置在 XML 解析器和模式验证器之间的 SAX 过滤器来完成。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。