我有一个不那么漂亮的XSD我试图清理。这就是它的样子: -
<xs:complexType name="A">
<xs:sequence>
<xs:element name="B">
<xs:complexType>
<xs:sequence>
<xs:element ref='Moniker' maxOccurs="1" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="type" type="xs:string" use="optional"/>
<xs:attribute name="value" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
我想将monicker的maxOccurs(这只是B的名称)为1而B具有属性&#34; type&#34;时,将元素B的定义更改为以下内容。使用类型字符串和另一个类型为字符串的属性值。
因此,当这些条件成立时,最终的架构应该如此: -
<xs:complexType name="A">
<xs:sequence>
<xs:element name="B" type="xs:string" />
</xs:sequence>
关于如何在XSLT中执行此操作的任何想法?
答案 0 :(得分:2)
首先,从XSLT身份转换开始,按原样复制元素
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
然后为您希望更改的元素编写模板(XSLT具有模板优先级的概念,并优先考虑匹配特定元素名称的模板)。您已经解释了匹配的规则,因此它应该只是将它们转换为XPATH表达式
<xsl:template match="xs:element[@name='B']
[xs:complexType/xs:sequence/xs:element[@ref='Moniker']/@maxOccurs='1']
[xs:complexType/xs:attribute[@name='type']/@type='xs:string']
[xs:complexType/xs:attribute[@name='value']/@type='xs:string']">
<xs:element name="B" type="xs:string" />
</xsl:template>
或者,您可以通过编写模板来匹配孩子 complexType 并将其转换为属性来接近它。
<xsl:template match="xs:element[@name='B']/xs:complexType
[xs:sequence/xs:element[@ref='Moniker']/@maxOccurs='1']
[xs:attribute[@name='type']/@type='xs:string']
[xs:attribute[@name='value']/@type='xs:string']">
<xsl:attribute name="type">xs:string</xsl:attribute>
</xsl:template>
试试这个XSLT
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="xs:element[@name='B']/xs:complexType
[xs:sequence/xs:element[@ref='Moniker']/@maxOccurs='1']
[xs:attribute[@name='type']/@type='xs:string']
[xs:attribute[@name='value']/@type='xs:string']">
<xsl:attribute name="type">xs:string</xsl:attribute>
</xsl:template>
</xsl:stylesheet>