使用Saxon-HE,我想解析一个xsd文件,获取结果树,并从给定的元素名称中获取结果子树,以及所有必需的simpleType和complexType(都使用类型引用和引用),例如解析像这样的文件:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="PSS" xmlns=""
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element maxOccurs="unbounded" name="Assistito">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="IDCittadino" type="IDCittadino"/>
<xs:element maxOccurs="unbounded" name="Struttura">
<xs:complexType>
<xs:sequence>
<xs:element name="CodiceStruttura" type="CodiceStruttura"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="IDCittadino">
<xs:restriction base="xs:string">
<xs:minLength value="20"/>
<xs:maxLength value="32"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="CodiceStruttura">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="8"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
我需要从名称为“ Struttura”的元素中获取子树,还需要从名称为“ CodiceStruttura”的simpleType中获取子树,例如:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="PSS" xmlns=""
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Struttura">
<xs:complexType>
<xs:sequence>
<xs:element name="CodiceStruttura" type="CodiceStruttura"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="CodiceStruttura">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="8"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
注释
预先感谢
答案 0 :(得分:1)
通常,我不建议使用模式文档的原始XML,建议使用模式编译器生成的模式组件模型,因为否则您将发现自己(a)复制了模式编译器,或者(b)弄错了,并且没有正确处理所有模式。
您可以通过多种方式以编程方式访问架构组件模型。 Saxon提供了两种方法(但都需要Saxon-EE)。 (a)您可以使用Saxon的模式处理器(使用com.saxonica.Validate -xsd:schema.xsd -scmout:schema.scm
)输出模式组件模型的XML表示形式。 (b)您可以使用一组扩展功能(从saxon:schema()
开始,从XSLT或XQuery访问模式组件模型。
作为替代方案,Xerces模式处理器为其内部模式组件模型提供了Java API,您也许可以使用Xalan(或实际上是Saxon)扩展功能来访问此API。
在所有这些情况下,提供的“架构组件模型”非常接近W3C XSD规范中描述的抽象架构组件模型。与使用原始模式文档的主要区别包括:(a)所有导入,包含和跨组件引用均已解决; (b)所有违约均已扩大; (c)模型组和属性组已扩展。
答案 1 :(得分:0)
我不确定没有任何基于模式解析/模式的XSLT或XQuery处理或模式对象模型的Saxon 9 HE是否适合该任务,它仅有的就是XSLT 3或XQuery 3.1,因此您需要使用XSLT 3和xsl:key
之类的语言的功能来遵循任何type
或ref
的交叉引用。
尝试为我创建的type
实现这一目标
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="3.0">
<xsl:param name="element-to-search" as="xs:QName" select="xs:QName('Struttura')"/>
<xsl:key name="element-ref" match="xs:element" use="resolve-QName(@name, .)"/>
<xsl:key name="type-ref" match="xs:complexType | xs:simpleType" use="resolve-QName(@name, .)"/>
<xsl:variable name="start-element" select="key('element-ref', $element-to-search)"/>
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:mode name="flatten" on-no-match="shallow-skip"/>
<xsl:template match="/*">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="$start-element"/>
<xsl:apply-templates select="$start-element//xs:element" mode="flatten"/>
</xsl:copy>
</xsl:template>
<xsl:template match="xs:element[@type and key('type-ref', resolve-QName(@type, .))]" mode="flatten">
<xsl:apply-templates select="key('type-ref', resolve-QName(@type, .))"/>
</xsl:template>
</xsl:stylesheet>
为您的示例输入创建(在https://xsltfiddle.liberty-development.net/eiZQaFw的在线示例)的输出
<xs:schema xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
id="PSS">
<xs:element maxOccurs="unbounded" name="Struttura">
<xs:complexType>
<xs:sequence>
<xs:element name="CodiceStruttura" type="CodiceStruttura"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="CodiceStruttura">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="8"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
因此,该方法找到了所引用的简单类型并添加了它,并为ref
属性使用了单独的键,您也许也可以添加它们,并且如果有的话,也可能是可行的(也许有些递归)一个没有包含和导入的单一模式模块,以及迈克尔·凯(Michael Kay)提到的更高级的模式功能。我不确定它是否会对模式进行任何健壮的处理,模式语言是否复杂,并且仅按您的要求进行复制也会造成问题(如您所见,maxOccurs="unbounded"
已通过简单方法进行了复制,您将需要添加一个模板,以禁止您在顶层放置的任何内容。
我也不确定通过将内联元素拉到顶层来构造无效的东西是否容易,如果您选择一个内联的局部作用域元素foo
作为起点,会发生什么但是还存在一个全局声明的且在其他地方引用的foo
元素吗?