我有一个简单的xml文件,它是一个属性列表(名称/值对):
<?xml version="1.0" encoding="ISO-8859-1"?>
<Attrs>
<Attr N="IsValid" V="true" />
<Attr N="ID" V="99099" />
</Attrs>
我想创建一个输出值的XSLT文件,但我似乎无法让它返回属性的值
这是我的xslt:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/Attrs">
<xsl:if test="Attr[@N='IsValid']">
--found IsValid
IsValid 1: <xsl:value-of select="current()/Attr[@V]"/>
IsValid 2: <xsl:value-of select="Attr[@V]"/>
</xsl:if>
<xsl:if test="Attr[@N='ID']">
--found ID
ID 1: <xsl:value-of select="current()/Attr[@V]"/>
ID 2: <xsl:value-of select="Attr[@V]"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
在找到适当的属性Name(N ='name')后,我无法获得'V'属性的值。我不知道如何选择@V值。
这是我的输出:
<?xml version="1.0" encoding="utf-8"?>
--found IsValid
IsValid 1:
IsValid 2:
--found ID
ID 1:
ID 2:
我在大多数情况下使用了Anthony的解决方案。我确实将模板匹配更改为仅使用Attr,然后使用选择stement来过滤我的名称。在大多数情况下,我只需要价值。在其他情况下,我需要自定义,这真的减少了我需要的模板数量。 (再次感谢帮助所有人的正确方向的开始)
<xsl:template match="Attr">
<xsl:choose>
<xsl:when test="@N='IsValid'">
<xsl:value-of select="@V" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@V" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
答案 0 :(得分:3)
您应该使用这些路径
current()/Attr/@V
和
Attr/@V
Xpath中[]的目的是描述一个谓词,这是一个必须是真元素的测试,如果要进行XPath,它就会被放置。
修改强>
试试这个: -
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/Attrs">
<xsl:for-each match="Attr">
<xsl:if test="@N='IsValid'">
--found IsValid
IsValid 1: <xsl:value-of select="current()/@V"/>
IsValid 2: <xsl:value-of select="@V"/>
</xsl:if>
<xsl:if test="@N='ID'">
--found ID
ID 1: <xsl:value-of select="current()/@V"/>
ID 2: <xsl:value-of select="@V"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
注意在谓词之外使用current()并没有多大意义,因为从输出中看到使用current()的路径与没有谓词的路径相同。
另一个更符合XSLT目标的版本(我也放弃了当前的())是: -
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/Attrs">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="Attr[@N='IsValid']">
--found IsValid
IsValid: <xsl:value-of select="@V" />
</xsl:template>
<xsl:template match="Attr[@N='ID']">
--found ID
ID: <xsl:value-of select="@V"/>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
foreach很慢,像这样拆分模板:
**编辑:**你打败了我..
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/Attrs">
<xsl:apply-templates select="Attr" />
</xsl:template>
<xsl:template match="Attr">
<xsl:if test="@N='IsValid'">
--found IsValid
IsValid 2: <xsl:value-of select="@V"/>
</xsl:if>
<xsl:if test="@N='ID'">
--found ID
ID 2: <xsl:value-of select="@V"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:1)
首先,除非重要的是属性出现在哪个顺序,否则你应该用XML表示它们,因为属性,例如:
<element IsValid='true' ID='2'/>
名称/值对是 的XML属性。 (只要值不是疯狂的长字符串或对象层次结构。)
也就是说,这是一组简单的模板,可以满足您的需求:
<xsl:template match="Attrs">
<output>
<xsl:apply-templates select="Attr"/>
</output>
</xsl:template>
<xsl:template match="Attr[@N='IsValid']">
<xsl:text>IsValid=</xsl:text>
<xsl:value-of select="@V"/>
</xsl:template>
<xsl:template match="Attr[@N='ID']">
<xsl:text>ID=</xsl:text>
<xsl:value-of select="@V"/>
</xsl:template>