使用XSLT将JSON转XML时,如何过滤数组元素并消除冗余值?
问题解决:XSLT 3.0转换JSON到XML时冗余值问题
使用XSLT 3.0转换包含数组的JSON到XML,仅需保留数组中的ar1、ar2元素,但转换后的XML出现了a、b、c的冗余值v1v2v3,以下是相关代码及解决方案:
输入JSON
{ "a": "v1", "arr": [ { "ar1": "av1", "ar2": "av2", "ar3": "av3", "ar4": "av4", "ar5": "av5", "ar6": "av6" } ], "b": "v2", "c": "v3" }
所用XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="fn" expand-text="yes"> <xsl:strip-space elements="*" /> <xsl:output method="xml" omit-xml-declaration="yes" indent="yes" /> <xsl:param name="jsonText" /> <xsl:param name="json" select="parse-json($jsonText)"/> <xsl:template name="init"> <body> <envelope> <dataset> <AA>{$json?a}</AA> <xsl:apply-templates select="$json => serialize(map { 'method' : 'json'} ) => json-to-xml()"/> </dataset> </envelope> </body> </xsl:template> <xsl:template match="fn:array[@key = 'arr']"> <xsl:iterate select="*"> <arr> <ar1>{fn:string[@key = 'ar1']}</ar1> <ar2>{fn:string[@key = 'ar2']}</ar2> </arr> </xsl:iterate> </xsl:template> </xsl:stylesheet>
实际输出XML
<body> <envelope> <dataset> <AA>v1</AA> <arr> <ar1>av1</ar1> <ar2>av2</ar2> </arr>v1v2v3 </dataset> </envelope> </body>
期望输出XML
<body> <envelope> <dataset> <AA>v1</AA> <arr> <ar1>av1</ar1> <ar2>av2</ar2> </arr> </dataset> </envelope> </body>
问题原因与解决方法
问题原因
原代码中$json => serialize(map { 'method' : 'json'} ) => json-to-xml()会将整个JSON转换为XML结构,其中包含a、b、c对应的fn:string元素。XSLT的默认模板会处理这些未匹配的fn:string元素,输出它们的文本内容,导致冗余的v1v2v3出现在结果中。
修改后的XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="fn" expand-text="yes"> <xsl:strip-space elements="*" /> <xsl:output method="xml" omit-xml-declaration="yes" indent="yes" /> <xsl:param name="jsonText" /> <xsl:param name="json" select="parse-json($jsonText)"/> <xsl:template name="init"> <body> <envelope> <dataset> <AA>{$json?a}</AA> <!-- 直接处理arr数组,避免转换整个JSON --> <xsl:apply-templates select="$json?arr" mode="json-array"/> </dataset> </envelope> </body> </xsl:template> <!-- 处理JSON数组 --> <xsl:template match="." mode="json-array"> <xsl:iterate select="?*"> <arr> <ar1>{?ar1}</ar1> <ar2>{?ar2}</ar2> </arr> </xsl:iterate> </xsl:template> <!-- 阻止默认模板输出其他字符串节点 --> <xsl:template match="fn:string" /> </xsl:stylesheet>
修改说明
- 直接处理目标数组:不再将整个JSON序列化后转XML,而是直接访问
$json?arr数组,通过模式模板单独处理,避免生成多余的XML节点; - 简化取值逻辑:使用JSON路径
?ar1直接获取数组元素中的对应值,代码更简洁高效; - 屏蔽默认模板输出:添加空模板匹配
fn:string,阻止默认模板输出a、b、c等不需要的文本内容; - 减少冗余转换:去掉不必要的序列化和XML转换步骤,提升处理效率。
内容的提问来源于stack exchange,提问作者Ujjwal Kumar Vivek
相关产品推荐
相关产品推荐

