调用XSL函数提取XML中Value元素文本的问题及解决方案
XSL自定义函数报错及XML转换解决方案
问题根源
你的代码存在三个核心问题:
- 自定义函数无返回语句:
<xsl:function>必须明确输出结果,原代码仅定义变量但未返回内容,导致函数无效,触发类似"function undefined"的错误(部分处理器会因函数无返回判定为未定义)。 - XPath路径错误:输入XML中不存在
<Object>节点,原函数里的//Object/Metadata无法匹配到任何内容。 - 模板逻辑不符合预期:原模板仅生成单个
<p>标签,无法实现每个<Value>对应一个<p>的需求。
修正后的XSL代码
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:my="http://itcinfotec.com/my-namespace" exclude-result-prefixes="xs my" version="2.0"> <xsl:strip-space elements="*"/> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <!-- 自定义函数:返回符合条件的Value节点序列 --> <xsl:function name="my:getRealUDProducts" as="node()*"> <xsl:param name="context"/> <!-- 修正XPath,直接匹配Metadata节点 --> <xsl:sequence select="$context/Metadata[@source='wt.part.WTPart|com.ptc.PHBase|com.ptc.PHModel']/Property[@token='number']/Value"/> </xsl:function> <xsl:template match="/"> <!-- 遍历函数返回的每个Value节点,生成对应的<p>标签 --> <xsl:for-each select="my:getRealUDProducts(.)"> <p> <xsl:value-of select="."/> </p> </xsl:for-each> </xsl:template> </xsl:stylesheet>
关键修改说明
- 函数返回逻辑:使用
<xsl:sequence>直接返回匹配到的<Value>节点序列,同时将函数返回类型改为node()*(表示零或多个节点),替代原错误的xs:string。 - XPath修正:去掉不存在的
//Object路径,直接从上下文节点匹配<Metadata>。 - 模板逻辑调整:通过
<xsl:for-each>遍历函数返回的每个节点,为每个<Value>生成独立的<p>标签,完全符合预期输出。 - 命名空间优化:将
my加入exclude-result-prefixes,避免命名空间污染输出结果。
备选简化方案(无需自定义函数)
如果不需要强制使用自定义函数,直接用模板匹配更简洁:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> <xsl:strip-space elements="*"/> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:template match="/"> <xsl:apply-templates select="Metadata[@source='wt.part.WTPart|com.ptc.PHBase|com.ptc.PHModel']/Property[@token='number']/Value"/> </xsl:template> <xsl:template match="Value"> <p><xsl:value-of select="."/></p> </xsl:template> </xsl:stylesheet>
内容的提问来源于stack exchange,提问作者ak5555
相关产品推荐
相关产品推荐

