使用XSLT/XPath转换XML为NodeSet并提取目标字段的XSLT示例咨询
实现方案
前提说明
- 你提供的示例XML包含两个命名空间,需要先在XSLT中声明对应命名空间才能正确匹配节点:
cal前缀对应命名空间http://example.com- 采样数据的默认命名空间
http://123.com,我们统一用sd作为前缀指代
- 如果输入中
<sampledata>部分已经是解析完成的DOM节点,可直接通过XPath取值;如果是转义后的XML字符串,需要先通过解析函数转换为节点集(NodeSet)再操作。
XSLT 2.0 完整示例(推荐,原生支持字符串转节点集)
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cal="http://example.com" xmlns:sd="http://123.com" exclude-result-prefixes="cal sd"> <!-- 场景1:sampledata已经是DOM节点,直接取值 --> <xsl:template match="/"> <!-- 赋值Code变量 --> <xsl:variable name="contractCode" select="/cal:process/cal:input/sd:sampledata/sd:Code/text()"/> <!-- 赋值印度对应货币变量 --> <xsl:variable name="indiaCurrency" select="/cal:process/cal:input/sd:sampledata/sd:List/sd:countries[sd:country='INDIA']/sd:currency/text()"/> <!-- 赋值英国对应货币变量 --> <xsl:variable name="ukCurrency" select="/cal:process/cal:input/sd:sampledata/sd:List/sd:countries[sd:country='UK']/sd:currency/text()"/> <!-- 示例输出,可替换为你自己的业务逻辑 --> <result> <Code><xsl:value-of select="$contractCode"/></Code> <IndiaCurrency><xsl:value-of select="$indiaCurrency"/></IndiaCurrency> <UKCurrency><xsl:value-of select="$ukCurrency"/></UKCurrency> </result> </xsl:template> <!-- 场景2:sampledata是XML字符串,先转节点集再取值 --> <!-- <xsl:template match="/"> <xsl:variable name="sampledataStr" select="/cal:process/cal:input/text()"/> <xsl:variable name="sampledataNode" select="parse-xml($sampledataStr)"/> <xsl:variable name="contractCode" select="$sampledataNode/sd:sampledata/sd:Code/text()"/> <xsl:variable name="indiaCurrency" select="$sampledataNode/sd:sampledata/sd:List/sd:countries[sd:country='INDIA']/sd:currency/text()"/> 后续逻辑和场景1一致 </xsl:template> --> </xsl:stylesheet>
XSLT 2.0内置parse-xml()函数,可直接将合法的XML字符串转换为节点集,不需要依赖扩展函数。
XSLT 1.0 示例
XSLT 1.0标准没有内置字符串转XML的函数,需要依赖不同XSLT引擎的扩展实现,以下是主流引擎的示例:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cal="http://example.com" xmlns:sd="http://123.com" xmlns:saxon="http://saxon.sf.net/" exclude-result-prefixes="cal sd saxon"> <!-- 场景1:sampledata已经是DOM节点,取值逻辑和2.0完全一致 --> <xsl:template match="/"> <xsl:variable name="contractCode" select="/cal:process/cal:input/sd:sampledata/sd:Code/text()"/> <xsl:variable name="indiaCurrency" select="/cal:process/cal:input/sd:sampledata/sd:List/sd:countries[sd:country='INDIA']/sd:currency/text()"/> <xsl:variable name="ukCurrency" select="/cal:process/cal:input/sd:sampledata/sd:List/sd:countries[sd:country='UK']/sd:currency/text()"/> <result> <Code><xsl:value-of select="$contractCode"/></Code> <IndiaCurrency><xsl:value-of select="$indiaCurrency"/></IndiaCurrency> <UKCurrency><xsl:value-of select="$ukCurrency"/></UKCurrency> </result> </xsl:template> <!-- 场景2:sampledata是XML字符串,用Saxon扩展函数转换 --> <!-- <xsl:template match="/"> <xsl:variable name="sampledataStr" select="/cal:process/cal:input/text()"/> <xsl:variable name="sampledataNode" select="saxon:parse($sampledataStr)"/> 后续取值逻辑同上 </xsl:template> --> <!-- 微软MSXML引擎场景2写法,替换扩展函数即可 --> <!-- 先声明命名空间:xmlns:msxsl="urn:schemas-microsoft-com:xslt" --> <!-- <xsl:variable name="sampledataNode" select="msxsl:node-set($sampledataStr)"/> --> </xsl:stylesheet>
不同引擎的扩展函数语法略有差异,可根据你使用的XSLT处理器选择对应实现。
内容的提问来源于stack exchange,提问作者Venkatesh Lu
相关产品推荐
相关产品推荐

