Java中XSLT转换XML到HTML时Base64图片处理异常求助
解决XML转HTML时Base64处理的数组越界及截断问题
1. 定位XSLT第65行的核心问题
报错ArrayIndexOutOfBoundsException指向XSLT第65行第9列,大概率是你手动处理Base64字符串的逻辑(比如固定长度截取、拆分)存在索引越界,或是电子发票XML中的Base64包含换行、空格等无效字符,导致计算长度时出错。
修复建议:
- 放弃手动拆分Base64的逻辑,改用内置或安全的扩展函数处理:
- XSLT 2.0+直接用
fn:base64-decode()解码; - XSLT 1.0调用Java的
Base64工具类处理(需引入命名空间)。
- XSLT 2.0+直接用
- 处理前先清理Base64中的无效字符:用
translate($base64Str, ' ', '')去掉换行、回车和空格。
2. 解决HTML截断与img标签src重复问题
HTML截断是因为转换过程中抛出异常导致提前终止,src重复则可能是异常触发后重复渲染了img标签。按以下步骤修复:
步骤1:修正XSLT的Base64处理逻辑
方案1(XSLT 2.0+)
<!-- 清理Base64并生成img标签 --> <xsl:variable name="cleanBase64" select="translate(//Invoice/ImageData, ' ', '')"/> <img src="data:image/png;base64,{$cleanBase64}" alt="发票二维码"/>
方案2(XSLT 1.0,依赖Java扩展)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:java="http://xml.apache.org/xslt/java" exclude-result-prefixes="java"> <!-- 清理Base64无效字符 --> <xsl:variable name="rawBase64" select="//Invoice/ImageData"/> <xsl:variable name="cleanBase64" select="java:java.lang.String.replaceAll($rawBase64, '[\r\n\s]', '')"/> <img src="data:image/png;base64,{$cleanBase64}" alt="发票二维码"/> </xsl:stylesheet>
步骤2:完善Java转换代码的异常处理
作为Java新手,你可能未捕获转换过程中的异常,导致转换中断后输出不完整。修改代码如下:
import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import java.io.File; import java.io.FileOutputStream; public class XmlToHtmlConverter { public static void main(String[] args) { try { TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(new StreamSource(new File("HI02023000042250.xslt"))); transformer.transform( new StreamSource(new File("invoice.xml")), new StreamResult(new FileOutputStream("output.html")) ); System.out.println("转换完成"); } catch (Exception e) { // 打印完整异常栈,精准定位问题 e.printStackTrace(); } } }
步骤3:验证电子发票Base64的有效性
电子发票的Base64可能存在格式问题,比如长度不是4的倍数(Base64标准要求),可以用以下代码验证并修复:
import java.util.Base64; public class Base64Validator { public static void main(String[] args) { String rawBase64 = "从XML中提取的Base64字符串"; // 清理无效字符 String cleaned = rawBase64.replaceAll("[\\r\\n\\s]", ""); // 补全Base64的=后缀(如果长度不是4的倍数) if (cleaned.length() % 4 != 0) { int padCount = 4 - (cleaned.length() % 4); cleaned += "=".repeat(padCount); } // 尝试解码验证 try { Base64.getDecoder().decode(cleaned); System.out.println("Base64格式有效"); } catch (IllegalArgumentException e) { System.out.println("Base64格式无效:" + e.getMessage()); } } }
3. 快速调试技巧
- 单独提取XML中的Base64字符串,用本地解码工具验证是否能生成正常图片;
- 在XSLT中添加调试输出,确认Base64的传递和清理是否正确:
<xsl:message>清理后Base64长度:<xsl:value-of select="string-length($cleanBase64)"/></xsl:message> <xsl:message>前100个字符:<xsl:value-of select="substring($cleanBase64, 1, 100)"/></xsl:message>
内容的提问来源于stack exchange,提问作者neylersin
相关产品推荐
相关产品推荐

