【发布时间】: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)”是有效的,即类型系统似乎在很大程度上是名义上的,唯一的例外是使用的“替代”,但我希望以明显的方式进行评估,即通过评估测试子句。