遍历XSLT中XML元素的所有属性
问题描述:
我试图使用<xsl:for-each select="@*">
来获取给定元素的所有属性,但是当我这样做时,我的<xsl:choose>
语句不执行。遍历XSLT中XML元素的所有属性
这里是我的工作元素:<textBox id="Airfare" value="" label="text 1"/>
下面是我使用的XSLT模板:
<xsl:template match="textBox">
<div>
<xsl:choose>
<xsl:when test="@label">
<xsl:value-of select="@label"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>No Label Defined</xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:element name="input">
<xsl:attribute name="type">text</xsl:attribute>
<xsl:for-each select="@*">
<xsl:choose>
<xsl:when test="@id">
<xsl:attribute name="name">form_<xsl:value-of select="@id"/></xsl:attribute>
<xsl:attribute name="id">form_<xsl:value-of select="@id"/></xsl:attribute>
</xsl:when>
<xsl:when test="@label">
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="current()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:element>
</div>
当我生成HTML使用PHP我得到这个:
<div>text 1<input type="text" id="Airfare" value="" label="text 1"></div>
正如您所看到的,它没有将form_
添加到id属性中,它没有生成名称属性,也没有跳过标签属性。
答
嗨,你已经取得2个错误:如果当前的属性是wrong.The正确的(在我当然认为)
- 测试:名称()=“ID”
- 选择的电流值属性应该使用'。'来选择。
基本上在for-each循环的主体中,您当前的元素是一个属性。这是一个配对名称和价值。所以使用name()会为您提供名称,并且默认情况下会选择该值。
<xsl:template match="textBox">
<div>
<xsl:choose>
<xsl:when test="@label">
<xsl:value-of select="@label"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>No Label Defined</xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:element name="input">
<xsl:attribute name="type">text</xsl:attribute>
<xsl:for-each select="@*">
<xsl:choose>
<xsl:when test="name() = 'id'">
<xsl:attribute name="name">form_<xsl:value-of select="."/>
</xsl:attribute>
<xsl:attribute name="id">form_<xsl:value-of select="."/>
</xsl:attribute>
</xsl:when>
<xsl:when test="@label">
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="current()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:element>
</div>
</xsl:template>
我建议你改变其他测试条款的测试条件。
PS这取决于你的XSL转换,但你可能会想删除创建新的HTML的白色空间属性,比如这一个:
<xsl:attribute name="id">
form_<xsl:value-of select="."/>
</xsl:attribute>
必须是:
<xsl:attribute name="name">form_<xsl:value-of select="."/>
答
<xsl:element name="input"> <xsl:attribute name="type">text</xsl:attribute> <xsl:for-each select="@*"> <xsl:choose> <xsl:when test="@id">
这测试当前节点(属性)是否具有名为0123的属性。由于属性本身不具有属性,因此测试永远不会成功。
下面是使用模板的简明XSLT溶液,没有<xsl:for-each>
和没有条件逻辑:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my" exclude-result-prefixes="my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vNoLabelVal" select="'No Label Defined'"/>
<xsl:template match="textBox">
<xsl:value-of select="concat(@label, substring($vNoLabelVal, 1 div not(@label)))"/>
<input type="text">
<xsl:apply-templates select="@*"/>
</input>
</xsl:template>
<xsl:template match="textBox/@*">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="textBox/@id">
<xsl:attribute name="name">
<xsl:value-of select="concat('form_', .)"/>
</xsl:attribute>
</xsl:template>
<xsl:template match="textBox/@label"/>
</xsl:stylesheet>
当该变换是在给定的XML文档施加:
<textBox id="Airfare" value="" label="text 1"/>
产生所需的正确结果:
当此XML文档施加text 1<input type="text" name="form_Airfare" value="" />
(缺少label
属性):
<textBox id="Airfare" value="" />
正确的结果产生:
No Label Defined<input type="text" name="form_Airfare" value="" />
好问题(1)。请参阅我的回答以解释问题以及符合XSLT精神的简短而简单的解决方案。 – 2010-06-17 15:39:46