XSLT 的严格编译,但没有在应用程序上验证输入 XML

Strict compilation of XSLT, but without validating the input XML on application

我有一个模式(根据之前的问题,但这次它在 FILLEDSQUARETYPE 上有一些“必需”属性)。

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
    xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1">

  <xs:complexType name="SQUARETYPE">
    <xs:sequence>
      <xs:element name="contains">
        <xs:complexType>
          <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element ref="SQUARE"/>
            <xs:element ref="TRIANGLE"/>
          </xs:choice>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
    <xs:attribute name="kind"/>
    <xs:attribute name="width" type="xs:int"/>
    <xs:attribute name="x" type="xs:int"/>
    <xs:attribute name="y" type="xs:int"/>
  </xs:complexType>
  <xs:complexType name="FILLEDSQUARETYPE">
    <xs:sequence>
      <xs:element name="contains">
        <xs:complexType>
          <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element ref="SQUARE"/>
            <xs:element ref="TRIANGLE"/>
          </xs:choice>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
    <xs:attribute name="kind"/>

    <xs:attribute name="colour" type="xs:string" use="required"/>
    <xs:attribute name="width" type="xs:int"  use="required"/>
    <xs:attribute name="x" type="xs:int"  use="required"/>
    <xs:attribute name="y" type="xs:int"  use="required"/>
  </xs:complexType>
  <xs:complexType name="TRIANGLETYPE">
    <xs:sequence>
      <xs:element name="contains">
        <xs:complexType>
          <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element ref="SQUARE"/>
            <xs:element ref="TRIANGLE"/>
          </xs:choice>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
    <xs:attribute name="rotation" type="xs:int"/>
    <xs:attribute name="x" type="xs:int"/>
    <xs:attribute name="y" type="xs:int"/>
  </xs:complexType>
  <xs:element name="SQUARE">
    <xs:alternative test="@kind = 'FILLEDSQUARETYPE'" type="FILLEDSQUARETYPE"/>
    <xs:alternative test="@kind = 'SQUARETYPE'" type="SQUARETYPE"/>
    <xs:alternative type="xs:error"/>
  </xs:element>
  <xs:element name="TRIANGLE">
    <xs:alternative type="TRIANGLETYPE"/>
  </xs:element>
  <xs:element name="rootShape">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="SQUARE"/>
        <xs:element ref="TRIANGLE"/>
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>

我有一个 XSLT,我可以针对此 XSD 进行编译,但有 0 个警告。 注意它使用“元素(标签,类型)”

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    exclude-result-prefixes="xs msxsl"
    version="2.0">

  <xsl:output method="xml" indent="yes" encoding="UTF-8" version="1.0"/>

  <xsl:import-schema schema-location="MessingAbout.xsd"/>
  <xsl:template match="/">
    <xsl:apply-templates select="SQUARE"/>
  </xsl:template>
  <xsl:template match="element(SQUARE,FILLEDSQUARETYPE)">
    <foo>
      <xsl:value-of select="@colour"/>
    </foo>
  </xsl:template>
</xsl:stylesheet>

我可以像这样将转换应用于 xml。

<?xml version="1.0" encoding="utf-8" ?>
<SQUARE x="1" y="2" width="234" kind="FILLEDSQUARETYPE" colour="red">
  <contains/>
</SQUARE>

并得到

<?xml version="1.0" encoding="UTF-8"?>
<foo>red</foo>

万岁!

但是...这是对我的“真实世界”场景的简化。 在我的真实世界场景中,源系统被优化为仅导出转换所需的 XML,(并且模式描述了一个乌托邦世界,其中所有数据都被导出,具有强制数据,即使那不是必需的)

因此,例如,转换不需要属性“width”、“x”、“y”,因此将被排除...像这样..

<?xml version="1.0" encoding="utf-8" ?>
<SQUARE kind="FILLEDSQUARETYPE" colour="red">
  <contains/>
</SQUARE>

如果我们现在将转换(使用 SchemaValidationMode.Strict)应用到这个 XML 那么撒克逊人会抱怨。

它会自动验证输入。

Validation error on line 2 column 46
  FORG0001: Required attribute @Q{}y is missing on element <SQUARE>
  Validating /SQUARE[1]
  See http://www.w3.org/TR/xmlschema11-1/#cvc-complex-type clause 4
Validation error on line 2 column 46
  FORG0001: Required attribute @Q{}x is missing on element <SQUARE>
  Validating /SQUARE[1]
  See http://www.w3.org/TR/xmlschema11-1/#cvc-complex-type clause 4
Validation error on line 2 column 46
  FORG0001: Required attribute @Q{}width is missing on element <SQUARE>
  Validating /SQUARE[1]
  See http://www.w3.org/TR/xmlschema11-1/#cvc-complex-type clause 4
Validation error on line 4 column 10
  XTTE1510: Three validation errors were reported. First error: Required attribute @Q{}y is
  missing on element <SQUARE>

尽管这些错误与我的 XSLT 无关,但在我的场景中这是一个问题,理想情况下我想关闭此行为,这样 saxon 就不会尝试验证与 XSLT 无关的内容XSLT 的执行。

有什么想法吗?

(我显然可以为导出的数据子集创建一个模式,但这实际上非常繁重,并且在需要有效地存在多种类型以有效描述相同的乌托邦数据时具有令人讨厌的含义,当不同的子集儿童出口。 我也可以将所有内容都变成可选的,但这会大大降低类型检查的价值)。

将模式告诉 XSLT 编译器的整个想法是让它知道在看到数据时会发生什么;编译器可以生成代码来假设数据会是什么样子。如果数据不符合模式,那么整个想法就会被否定。

很难具体说明如果接受了无效数据会出现什么问题,但 XSLT 优化器大量使用了架构知识。举一个简单的例子,如果您的样式表 <xsl:if test="exists(*)">,并且模式表明该元素将始终有子元素,那么 XSLT 处理器很可能已将其优化为“如果为真”。