如何使用XSLT读取XML中的自定义处理指令(Prolog)?
没问题!我来帮你搞定读取自定义Prolog标记的XSLT实现。先结合常见的场景给你示例代码,你可以根据自己实际的XML结构和Prolog格式调整。
假设你的消息XML结构是这样的
首先先定义一个典型的消息结构,其中<prolog>节点里是用分号分隔的键值对指令:
<message> <prolog>routeTo=processingQueue;priority=high;notifyAdmin=true</prolog> <content>用户提交的业务消息内容</content> </message>
读取并解析Prolog的XSLT代码
下面的XSLT会提取Prolog内容,拆分指令,然后根据不同的指令执行对应的处理/路由逻辑:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 匹配消息根节点 --> <xsl:template match="/message"> <!-- 提取Prolog的文本内容到变量 --> <xsl:variable name="prologContent" select="prolog/text()"/> <!-- 调用递归模板解析所有指令 --> <xsl:call-template name="parsePrologInstructions"> <xsl:with-param name="inputText" select="$prologContent"/> </xsl:call-template> </xsl:template> <!-- 递归拆分Prolog中的每个指令(分号分隔) --> <xsl:template name="parsePrologInstructions"> <xsl:param name="inputText"/> <xsl:param name="delimiter" select="';'"/> <xsl:if test="$inputText != ''"> <!-- 截取第一个指令 --> <xsl:variable name="currentCmd" select="substring-before(concat($inputText, $delimiter), $delimiter)"/> <!-- 剩余未处理的指令文本 --> <xsl:variable name="remainingText" select="substring-after($inputText, $delimiter)"/> <!-- 解析单个指令的键值对 --> <xsl:call-template name="parseKeyValuePair"> <xsl:with-param name="cmdText" select="$currentCmd"/> </xsl:call-template> <!-- 递归处理剩余指令 --> <xsl:call-template name="parsePrologInstructions"> <xsl:with-param name="inputText" select="$remainingText"/> </xsl:call-template> </xsl:if> </xsl:template> <!-- 解析单个指令的键和值(等号分隔) --> <xsl:template name="parseKeyValuePair"> <xsl:param name="cmdText"/> <xsl:param name="separator" select="'='"/> <xsl:if test="contains($cmdText, $separator)"> <xsl:variable name="cmdKey" select="normalize-space(substring-before($cmdText, $separator))"/> <xsl:variable name="cmdValue" select="normalize-space(substring-after($cmdText, $separator))"/> <!-- 根据指令键执行对应的处理逻辑 --> <xsl:choose> <xsl:when test="$cmdKey = 'routeTo'"> <!-- 示例:输出路由目标,你可以替换成实际的路由操作 --> <xsl:message>路由消息到队列:<xsl:value-of select="$cmdValue"/></xsl:message> <routing-target><xsl:value-of select="$cmdValue"/></routing-target> </xsl:when> <xsl:when test="$cmdKey = 'priority'"> <!-- 示例:设置消息优先级 --> <xsl:message>设置消息优先级为:<xsl:value-of select="$cmdValue"/></xsl:message> <message-priority><xsl:value-of select="$cmdValue"/></message-priority> </xsl:when> <xsl:when test="$cmdKey = 'notifyAdmin'"> <!-- 示例:触发管理员通知逻辑 --> <xsl:if test="$cmdValue = 'true'"> <xsl:message>触发管理员通知</xsl:message> <admin-notification enabled="true"/> </xsl:if> </xsl:when> <!-- 可以继续扩展更多指令的处理逻辑 --> <xsl:otherwise> <xsl:message>未知指令:<xsl:value-of select="$cmdKey"/></xsl:message> <unknown-instruction key="{$cmdKey}" value="{$cmdValue}"/> </xsl:otherwise> </xsl:choose> </xsl:if> </xsl:template> </xsl:stylesheet>
如果你用的是XSLT 2.0+
可以用tokenize()函数简化拆分逻辑,代码会更简洁:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/message"> <xsl:variable name="prologContent" select="prolog/text()"/> <!-- 直接拆分所有指令 --> <xsl:for-each select="tokenize($prologContent, ';')"> <xsl:variable name="cmdParts" select="tokenize(., '=')"/> <xsl:variable name="cmdKey" select="normalize-space($cmdParts[1])"/> <xsl:variable name="cmdValue" select="normalize-space($cmdParts[2])"/> <!-- 同样的处理逻辑 --> <xsl:choose> <xsl:when test="$cmdKey = 'routeTo'"> <routing-target><xsl:value-of select="$cmdValue"/></routing-target> </xsl:when> <!-- 其他指令处理... --> </xsl:choose> </xsl:for-each> </xsl:template> </xsl:stylesheet>
注意事项
如果你的Prolog不是键值对格式,而是XML结构化的(比如<prolog><instruction key="routeTo" value="xxx"/></prolog>),只需要调整匹配逻辑,直接遍历<instruction>节点读取属性即可,代码会更简单。
内容的提问来源于stack exchange,提问作者gmeka
相关产品推荐
相关产品推荐

