使用类似于调用模板的方法向输出XML添加属性
我已经找了几个星期了,我几乎要放弃了。我有一个基于XSD定义输出XML文件的XSLT脚本。我的问题在于这段代码:使用类似于调用模板的方法向输出XML添加属性,xml,xslt,Xml,Xslt,我已经找了几个星期了,我几乎要放弃了。我有一个基于XSD定义输出XML文件的XSLT脚本。我的问题在于这段代码: <!-- I wish this could work --> <xsl:if test="$minOccurs"> <xsl:attribute name="minOccurs"><xsl:value-of select="$minOccurs"/></xsl:attribute>
<!-- I wish this could work -->
<xsl:if test="$minOccurs">
<xsl:attribute name="minOccurs"><xsl:value-of select="$minOccurs"/></xsl:attribute>
</xsl:if>
<xsl:choose>
<xsl:when test="@ref">
<xsl:variable name="elementRef" select="current()/@ref"/>
<xsl:for-each select="//xs:element[@name=$elementRef]">
<xsl:call-template name="element">
<xsl:with-param name="minOccurs" select="./@minOccurs"/>
</xsl:call-template>
</xsl:for-each>
</xsl:when>
<!-- abridged -->
</xsl:choose>
</xsl:template>
示例输入,类型可以任意嵌套:
<xs:element name="rootElement">
<xs:complexType>
<xs:sequence>
<xs:element ref="r1" minOccurs="0" />
<xs:element ref="r2" minOccurs="0" />
<xs:element ref="r3" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element ref="r4" minOccurs="0" />
<xs:element ref="r5" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- I wish this could work -->
<xsl:if test="$minOccurs">
<xsl:attribute name="minOccurs"><xsl:value-of select="$minOccurs"/></xsl:attribute>
</xsl:if>
<xsl:choose>
<xsl:when test="@ref">
<xsl:variable name="elementRef" select="current()/@ref"/>
<xsl:for-each select="//xs:element[@name=$elementRef]">
<xsl:call-template name="element">
<xsl:with-param name="minOccurs" select="./@minOccurs"/>
</xsl:call-template>
</xsl:for-each>
</xsl:when>
<!-- abridged -->
</xsl:choose>
</xsl:template>
XSL:
<!-- I wish this could work -->
<xsl:if test="$minOccurs">
<xsl:attribute name="minOccurs"><xsl:value-of select="$minOccurs"/></xsl:attribute>
</xsl:if>
<xsl:choose>
<xsl:when test="@ref">
<xsl:variable name="elementRef" select="current()/@ref"/>
<xsl:for-each select="//xs:element[@name=$elementRef]">
<xsl:call-template name="element">
<xsl:with-param name="minOccurs" select="./@minOccurs"/>
</xsl:call-template>
</xsl:for-each>
</xsl:when>
<!-- abridged -->
</xsl:choose>
</xsl:template>
输出如下内容:
<!-- I wish this could work -->
<xsl:if test="$minOccurs">
<xsl:attribute name="minOccurs"><xsl:value-of select="$minOccurs"/></xsl:attribute>
</xsl:if>
<xsl:choose>
<xsl:when test="@ref">
<xsl:variable name="elementRef" select="current()/@ref"/>
<xsl:for-each select="//xs:element[@name=$elementRef]">
<xsl:call-template name="element">
<xsl:with-param name="minOccurs" select="./@minOccurs"/>
</xsl:call-template>
</xsl:for-each>
</xsl:when>
<!-- abridged -->
</xsl:choose>
</xsl:template>
<rootElement>
<r1 minOccurs="0" />
<r2 minOccurs="0" />
<r3 minOccurs="0">
<r4/>
<r5/>
</r3>
</rootElement>
我正在使用进行递归调用,效果很好。但是,我不能添加属性,我在网上也读了很多。那么我如何更改它以添加属性呢?给定这个XML输入
<!-- I wish this could work -->
<xsl:if test="$minOccurs">
<xsl:attribute name="minOccurs"><xsl:value-of select="$minOccurs"/></xsl:attribute>
</xsl:if>
<xsl:choose>
<xsl:when test="@ref">
<xsl:variable name="elementRef" select="current()/@ref"/>
<xsl:for-each select="//xs:element[@name=$elementRef]">
<xsl:call-template name="element">
<xsl:with-param name="minOccurs" select="./@minOccurs"/>
</xsl:call-template>
</xsl:for-each>
</xsl:when>
<!-- abridged -->
</xsl:choose>
</xsl:template>
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="rootElement">
<xs:complexType>
<xs:sequence>
<!-- replaced original @ref with @name -->
<xs:element name="r1" minOccurs="0" />
<xs:element name="r2" minOccurs="0" />
<xs:element name="r3" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="r4" minOccurs="0" />
<xs:element name="r5" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
以下XSLT
<!-- I wish this could work -->
<xsl:if test="$minOccurs">
<xsl:attribute name="minOccurs"><xsl:value-of select="$minOccurs"/></xsl:attribute>
</xsl:if>
<xsl:choose>
<xsl:when test="@ref">
<xsl:variable name="elementRef" select="current()/@ref"/>
<xsl:for-each select="//xs:element[@name=$elementRef]">
<xsl:call-template name="element">
<xsl:with-param name="minOccurs" select="./@minOccurs"/>
</xsl:call-template>
</xsl:for-each>
</xsl:when>
<!-- abridged -->
</xsl:choose>
</xsl:template>
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="xs:element">
<xsl:element name="{@name}">
<xsl:if test="@minOccurs">
<xsl:attribute name="minOccurs">
<xsl:value-of select="@minOccurs"/>
</xsl:attribute>
</xsl:if>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
将生成以下XML输出
<!-- I wish this could work -->
<xsl:if test="$minOccurs">
<xsl:attribute name="minOccurs"><xsl:value-of select="$minOccurs"/></xsl:attribute>
</xsl:if>
<xsl:choose>
<xsl:when test="@ref">
<xsl:variable name="elementRef" select="current()/@ref"/>
<xsl:for-each select="//xs:element[@name=$elementRef]">
<xsl:call-template name="element">
<xsl:with-param name="minOccurs" select="./@minOccurs"/>
</xsl:call-template>
</xsl:for-each>
</xsl:when>
<!-- abridged -->
</xsl:choose>
</xsl:template>
<?xml version="1.0" encoding="UTF-8"?>
<rootElement>
<r1 minOccurs="0"/>
<r2 minOccurs="0"/>
<r3 minOccurs="0">
<r4 minOccurs="0"/>
<r5 minOccurs="0"/>
</r3>
</rootElement>
根据要求。它是如何失败的?您的代码没有足够的上下文来查看错误,例如,我们看到了对变量的引用,但忽略了声明。我得到了正确的结构,包含元素,但没有属性minOccurs。因为我们无法看到name=“element”的模板,我们怎么才能告诉你出了什么问题呢?谢谢你指出,我发现还有一个错误。这令人困惑。。。
<!-- I wish this could work -->
<xsl:if test="$minOccurs">
<xsl:attribute name="minOccurs"><xsl:value-of select="$minOccurs"/></xsl:attribute>
</xsl:if>
<xsl:choose>
<xsl:when test="@ref">
<xsl:variable name="elementRef" select="current()/@ref"/>
<xsl:for-each select="//xs:element[@name=$elementRef]">
<xsl:call-template name="element">
<xsl:with-param name="minOccurs" select="./@minOccurs"/>
</xsl:call-template>
</xsl:for-each>
</xsl:when>
<!-- abridged -->
</xsl:choose>
</xsl:template>