【问题标题】:Strict compilation of XSLT, but without validating the input XML on applicationXSLT 的严格编译,但不验证应用程序上的输入 XML
【发布时间】:2020-11-10 11:56:49
【问题描述】:

我有一个架构(根据之前的问题,但这次它在 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>

如果我们现在对这个 XML 应用转换(使用 SchemaValidationMode.Strict),那么 saxon 会抱怨。

它会自动验证输入。

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。

有什么想法吗?

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

【问题讨论】:

  • 哪一部分相关,哪一部分不相关?您想在不验证 XML 的情况下针对 XML 运行 XSLT?如果您不验证,您如何期望使用使用模式类型的匹配模式的模板?您当然可以根据要使用的元素名称编写模板匹配并关闭验证,但我不知道您如何使用 match="element(SQUARE,FILLEDSQUARETYPE)" 但希望它可以处理无效的 XML 输入。
  • 是的,我想根据未经验证的输入评估 XSLT。如果在运行 XSLT 时对类型进行延迟评估,并且存在推断类型所需的所有内容,则“元素(SQUARE,FILLEDSQUARETYPE)”是有效的,即类型系统似乎在很大程度上是名义上的,唯一的例外是使用的“替代”,但我希望以明显的方式进行评估,即通过评估测试子句。

标签: xslt-2.0 saxon xslt-3.0


【解决方案1】:

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

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

【讨论】:

  • 我认为类型检查比优化更有价值,我想知道是否可以关闭优化,并且类型是懒惰地评估并名义上从模式中推断出来,而不是急切地验证.我正在尝试复制一个可以做到这一点的系统。代码被编译并针对全局模式进行类型检查,但数据直到运行时才被读取,并且只有在需要时才读取,如果不需要,则不读取,如果不存在则无关紧要。跨度>
  • 它的类型相当于树在树林里发出的声音,如果没有人听到它......对于撒克逊人来说,树必须明显地存在......即使它的存在是(逻辑上)与变换无关。感觉就像是一种偶然的耦合。
  • 我认为我唯一的选择是削弱架构以使所有内容都可选,然后输入始终“正确”,但至少我可以检测到引用架构中不存在的内容的无效路径跨度>
  • 感谢您的帮助。我会将您的答案标记为答案....如果我可以关闭优化器并解决此问题,请告诉我
  • 其实只是出于兴趣,XSLT 现在支持流式传输,我以为会有类似的问题?
猜你喜欢
  • 1970-01-01
  • 2012-01-13
  • 1970-01-01
  • 2022-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多