是否有一种简单的(XSLT?)(最好是自动化的)方法,可以将XSD文件中的xsd:choice构造更改为没有选择构造的定义。例如,我得到一个包含以下部分的XSD:
<xsd:choice minOccurs="1" maxOccurs="1">
<xsd:element name="ExistingBuild" type="ExistingBuild" nillable="false"/>
<xsd:element name="NewBuild" type="NewBuild" nillable="false"/>
</xsd:choice>
此XSD需要导入不支持选择构造的应用程序中。我已经手动更改了XSD,以将段定义如下:
<xsd:element name="ExistingBuild" type="ExistingBuild" nillable="false" minOccurs="0" maxOccurs="1"/>
<xsd:element name="NewBuild" type="NewBuild" nillable="false" minOccurs="0" maxOccurs="1"/>
生成的XSD可以正确导入并达到目的。因此,我可以手动更改此设置。
但是,该XSD将来会定期更新,我需要在每次发布新版本时手动对其进行更改。为了防止人为错误,我希望自动执行此转换。 XSLT是否可以解决此问题,我将如何定义这样的XSLT解决方案?
在此先感谢您的帮助。
答案 0 :(得分:0)
编写XSLT删除xsd:choice
元素并不难
从身份模板开始(该模板处理您不想更新的内容)
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
添加模板以忽略xsd:choice
<xsl:template match="xsd:choice">
<xsl:apply-templates />
</xsl:template>
然后添加一个模板来处理子xsd:elements
<xsl:template match="xsd:choice/xsd:element">
<xsd:element minOccurs="0" maxOccurs="{../@maxOccurs}">
<xsl:apply-templates select="@*" />
</xsd:element>
</xsl:template>
将所有内容放在一起就可以得到...
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="https://www.w3.org/2001/XMLSchema"
version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="xsd:choice">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="xsd:choice/xsd:element">
<xsd:element minOccurs="0" maxOccurs="{../@maxOccurs}">
<xsl:apply-templates select="@*" />
</xsd:element>
</xsl:template>
</xsl:stylesheet>
在http://xsltfiddle.liberty-development.net/bFDb2Di上以不完整的架构查看实际运行情况