如何在XSLT中通过变量指定节点名称获取XML节点值?
问题:通过变量引用XML节点名称获取值失败的解决办法
我正在学习XML/XSLT,若问题较为基础还请见谅。我想要获取XML中特定节点的值,该节点的名称存储在XSLT的变量中。例如,我将值“Monat2”存入变量monat,期望获取“Monat2”节点下的值。我尝试使用<xsl:value-of select="*[local-name()=$monat]"/>来引用节点,但似乎无法生效。请帮忙指出我哪里出错了?
源XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <source> <source_records> <Klnr>123456</Klnr> <Name>BestRun</Name> <Pnr>98765 </Pnr> <EmpName>Joe Bloggs</EmpName> <LA>10 </LA> <Lohnart>GEHALT</Lohnart> <Monat1>4145.00 </Monat1> <Monat2>4513.00 </Monat2> <Monat3>4329.00 </Monat3> <Monat4>4329.00 </Monat4> <Monat5>4329.00 </Monat5> <Monat6>0.00 </Monat6> <Monat7>0.00 </Monat7> <Monat8>0.00 </Monat8> <Monat9>0.00 </Monat9> <Monat10>0.00 </Monat10> <Monat11>0.00 </Monat11> <Monat12>0.00 </Monat12> <GESAMT>21645.00 </GESAMT> </source_records> <source_records> <Klnr>123456 </Klnr> <Name>BestRun</Name> <Pnr>98765 </Pnr> <EmpName>Joe Bloggs</EmpName> <LA>70 </LA> <Lohnart>SACHBEZUG PKW</Lohnart> <Monat1>510.00 </Monat1> <Monat2>510.00 </Monat2> <Monat3>510.00 </Monat3> <Monat4>510.00 </Monat4> <Monat5>510.00 </Monat5> <Monat6>0.00 </Monat6> <Monat7>0.00 </Monat7> <Monat8>0.00 </Monat8> <Monat9>0.00 </Monat9> <Monat10>0.00 </Monat10> <Monat11>0.00 </Monat11> <Monat12>0.00 </Monat12> <GESAMT>2550.00 </GESAMT> </source_records> </source>
原XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > <!-- <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> --> <xsl:template match="/source"> <!-- month to be retrieved --> <xsl:variable name="monat" select="Monat2" /> <!-- cycle through each record --> <xsl:for-each select="source_records"> <!-- rebuild --> <source_records> <employeeID> <xsl:value-of select="normalize-space(Pnr)" /> </employeeID> <name> <xsl:value-of select="EmpName" /> </name> <payCode> <xsl:value-of select="normalize-space(LA)" /> </payCode> <amount> <xsl:value-of select="*[local-name()=$monat]"/> </amount> </source_records> </xsl:for-each> </xsl:template> </xsl:stylesheet>
错误原因与解决办法
核心错误
你定义变量monat的方式有误:
<xsl:variable name="monat" select="Monat2" />
这里的select="Monat2"是让XSLT在当前上下文(/source节点)下查找名为Monat2的子节点,但你的Monat2节点实际嵌套在source_records内部,因此这个变量最终获取的是空值,自然无法匹配到目标节点。
正确写法
需要把变量赋值为字符串字面量,用单引号或双引号包裹目标节点名称:
<xsl:variable name="monat" select="'Monat2'" />
修正后的完整XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:template match="/source"> <!-- month to be retrieved --> <xsl:variable name="monat" select="'Monat2'" /> <!-- cycle through each record --> <xsl:for-each select="source_records"> <!-- rebuild --> <source_records> <employeeID> <xsl:value-of select="normalize-space(Pnr)" /> </employeeID> <name> <xsl:value-of select="EmpName" /> </name> <payCode> <xsl:value-of select="normalize-space(LA)" /> </payCode> <amount> <xsl:value-of select="*[local-name()=$monat]"/> </amount> </source_records> </xsl:for-each> </xsl:template> </xsl:stylesheet>
补充说明
- 如果XML没有使用命名空间,选择器可以简化为
*[name()=$monat],效果和local-name()一致 - 给变量赋值字符串时,必须用引号包裹,否则XSLT会将其当作节点路径解析
内容的提问来源于stack exchange,提问作者AJW
相关产品推荐
相关产品推荐

