如何让命令行传入的XML文本在XSLT中不被转义?
XML片段通过命令行传入XSLT后转义问题的解决方案
概述
需要将外部进程动态生成的XML片段通过命令行传入XSLT进行处理。
问题
将XML作为参数传入后,XSLT处理时会自动转义<>符号为<>,导致无法被当作XML解析。
相关文件与命令
XML文件(test.xml)
<?xml version="1.0" encoding="UTF-8"?> <document> <h2>General Introduction</h2> <h3>Project Overview</h3> <h3>Goals and Challenges</h3> <h2>Installation</h2> <h3>Initial Configuration</h3> <options></options> <h4>Configuration File</h4> <h3>Deployment</h3> <h4>On a Local Server</h4> <h4>On a Remote Server</h4> <h2>Usage</h2> <h3>Basic Commands</h3> <h3>Advanced Options</h3> </document>
XSLT文件(test.xslt)
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:param name="optionsContent"/> <!-- 传入的变量 --> <xsl:template match="/document"> <html> <body> <xsl:apply-templates/> <xsl:apply-templates select="$optionsContent"/> <!-- 尝试处理带尖括号的变量内容 --> </body> </html> </xsl:template> <xsl:template match="options"> <h2>Options</h2> <p>Some options</p> </xsl:template> </xsl:stylesheet>
执行命令
java -jar /usr/share/java/Saxon-HE-9.9.1.5.jar \ -s:test.xml \ -xsl:test.xslt \ -o:test.html \ optionsContent='<options></options>' # 此处为传入的XML片段参数
当前输出结果
<html> <body> General Introduction Project Overview Goals and Challenges Installation Initial Configuration <h2>Options</h2> <p>Some options</p> Configuration File Deployment On a Local Server On a Remote Server Usage Basic Commands Advanced Options <options></options></body> <!-- 尖括号被转义,无法作为XML节点处理 --> </html>
核心问题
如何让optionsContent的内容被当作XML而非带转义符号的纯文本处理?
解决方案
方法一:在XSLT中解析字符串为XML节点
利用XSLT 2.0支持的<xsl:parse>函数,将传入的字符串参数解析为XML节点集,之后即可正常应用模板处理。
修改后的XSLT文件:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:param name="optionsContent"/> <!-- 将字符串参数解析为XML节点 --> <xsl:variable name="parsedOptions"> <xsl:parse select="$optionsContent"/> </xsl:variable> <xsl:template match="/document"> <html> <body> <xsl:apply-templates/> <!-- 对解析后的XML节点应用模板 --> <xsl:apply-templates select="$parsedOptions/*"/> </body> </html> </xsl:template> <xsl:template match="options"> <h2>Options</h2> <p>Some options</p> </xsl:template> </xsl:stylesheet>
执行原命令即可得到正确结果,传入的<options></options>会被当作XML节点,触发对应的模板输出<h2>Options</h2><p>Some options</p>。
方法二:通过临时文件传递XML片段
如果命令行环境对特殊字符传递有限制,可先将XML片段写入临时文件,再传递文件路径作为参数,在XSLT中用document()函数加载。
步骤1:生成临时文件
echo '<options></options>' > temp-options.xml
步骤2:修改命令行参数
java -jar /usr/share/java/Saxon-HE-9.9.1.5.jar \ -s:test.xml \ -xsl:test.xslt \ -o:test.html \ optionsContent='temp-options.xml'
步骤3:修改XSLT文件加载外部XML
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:param name="optionsContent"/> <!-- 通过文件路径加载XML内容 --> <xsl:variable name="optionsXml" select="document($optionsContent)"/> <xsl:template match="/document"> <html> <body> <xsl:apply-templates/> <xsl:apply-templates select="$optionsXml/*"/> </body> </html> </xsl:template> <xsl:template match="options"> <h2>Options</h2> <p>Some options</p> </xsl:template> </xsl:stylesheet>
内容的提问来源于stack exchange,提问作者fauve
相关产品推荐
相关产品推荐

