Java XSLT转换器处理含无效命名空间XML失败求助
问题原因及解决方法:XML命名空间导致XSLT匹配失败
你遇到的问题根本不是TransformerFactory在验证Schema,而是XSLT模板没有正确匹配带命名空间的XML元素。
核心原因
你的XML里所有元素(<Result>、<Item>、<id>)都属于http://invalid.schema.org/123命名空间,但你的XSLT模板里写的match="id",是匹配没有命名空间的<id>元素。两者完全不匹配,所以XSLT找不到要修改的节点,看起来就像“转换完全无法执行”。
而当你移除XML里的命名空间后,<id>没有了命名空间,正好和XSLT里的match="id"匹配上,所以转换正常运行。
解决方法
有两种常用的修复方式:
方法1:在XSLT中声明目标命名空间,用前缀匹配元素
这是最规范的做法,在XSLT的<xsl:stylesheet>标签里声明目标命名空间并指定前缀,然后用前缀匹配对应的元素:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:data="http://invalid.schema.org/123"> <xsl:template match="/"> <xsl:apply-templates select="*"/> </xsl:template> <xsl:template match="*"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 用前缀匹配命名空间下的id元素 --> <xsl:template match="data:id"> <xsl:copy> *** </xsl:copy> </xsl:template> </xsl:stylesheet>
方法2:忽略命名空间匹配(不推荐)
如果不想处理命名空间,可以通过local-name()函数匹配元素的本地名称,但这种方式会忽略命名空间的语义,可能引发其他问题,仅作为临时方案:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <xsl:apply-templates select="*"/> </xsl:template> <xsl:template match="*"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 匹配所有本地名称为id的元素,不管命名空间 --> <xsl:template match="*[local-name()='id']"> <xsl:copy> *** </xsl:copy> </xsl:template> </xsl:stylesheet>
补充说明
Java的TransformerFactory默认不会验证XML的Schema,只有当你显式调用factory.setSchema(...)配置Schema后,才会开启验证。所以你不需要找“禁用验证”的方法,问题的根源完全在XSLT的匹配逻辑上。
内容的提问来源于stack exchange,提问作者Vinicius Carvalho
相关产品推荐
相关产品推荐

