使用Saxon XSLT引擎处理XML时如何让XSL文件定位所需XSD文件
问题描述
项目目录结构
src/main ├── assembly │ └── package.xml ├── java │ └── org │ └── legible │ ├── kafka │ │ ├── CamelSftpSourceConnector.java │ │ ├── CamelSftpSourceConnectorConfig.java │ │ ├── CamelSftpSourceTask.java │ │ ├── CamelSourceTask.java │ │ └── package-info.java │ └── reference_tag_converter │ └── ReferenceTagTransformer.java └── resources ├── schemas │ ├── ONIX_BookProduct_3.0_reference.xsd │ ├── ONIX_BookProduct_3.0_short.xsd │ ├── ONIX_BookProduct_CodeLists.xsd │ └── ONIX_XHTML_Subset.xsd ├── switch-onix-3.0-tagnames-2.0_v1.3.xsl └── switch-onixmessage-tag.xsl
问题代码
ReferenceTagTransformer类中实例化XSLT转换器的代码如下:
StreamSource switchOnixMessageTagStylesheet = new StreamSource(this.getClass().getClassLoader().getResourceAsStream("switch-onixmessage-tag.xsl")); StreamSource transformReferenceTagStylesheet = new StreamSource(this.getClass().getClassLoader().getResourceAsStream("switch-onix-3.0-tagnames-2.0_v1.3.xsl")); Processor processor = new Processor(false); XsltCompiler compiler = processor.newXsltCompiler(); XsltExecutable switchOnixMessageStylesheet = compiler.compile(switchOnixMessageTagStylesheet); XsltTransformer onixMessageTagTransformer = switchOnixMessageStylesheet.load(); XsltExecutable convertTagsStylesheet = compiler.compile(transformReferenceTagStylesheet); XsltTransformer referenceTagTransformer = convertTagsStylesheet.load(); referenceTagTransformer.setParameter(new QName("result-document"), new XdmAtomicValue(Paths.get("", "temp.xml").toString())); // path to XSD schemas referenceTagTransformer.setParameter(new QName("input-path"), new XdmAtomicValue("schemas"));
问题现象
调用转换器的transform方法时,样式表抛出错误,无法解析赋值给input-path变量的schemas路径。
解决方案
问题原因
你当前传入的schemas是相对路径,XSLT执行时的默认工作目录不是项目的resources目录,所以无法直接定位到schema文件。如果项目是打包成jar包运行,jar包内部的资源也无法通过普通文件路径直接访问。
分场景处理方案
场景1:打包后resources目录会被解压到文件系统
直接读取schemas目录的绝对路径传入即可,代码修改如下:
// 获取schemas目录的绝对路径 URL schemasUrl = this.getClass().getClassLoader().getResource("schemas"); String schemasAbsolutePath = Paths.get(schemasUrl.toURI()).toString(); referenceTagTransformer.setParameter(new QName("input-path"), new XdmAtomicValue(schemasAbsolutePath));
场景2:项目打包为jar包运行,resources目录未解压
XSLT的document()方法无法直接读取jar包内部的资源,你需要先将schemas目录复制到系统临时目录,再传入临时目录的路径:
import java.nio.file.StandardCopyOption; // 创建临时目录存放schema文件 Path tempSchemasDir = Files.createTempDirectory("onix_schemas_"); // 逐个将resources下的schema文件复制到临时目录 List<String> schemaFiles = Arrays.asList( "ONIX_BookProduct_3.0_reference.xsd", "ONIX_BookProduct_3.0_short.xsd", "ONIX_BookProduct_CodeLists.xsd", "ONIX_XHTML_Subset.xsd" ); for (String fileName : schemaFiles) { try (InputStream is = this.getClass().getClassLoader().getResourceAsStream("schemas/" + fileName)) { Files.copy(is, tempSchemasDir.resolve(fileName), StandardCopyOption.REPLACE_EXISTING); } } // 传入临时目录路径 referenceTagTransformer.setParameter(new QName("input-path"), new XdmAtomicValue(tempSchemasDir.toString())); // 转换完成后记得删除临时目录释放空间
内容的提问来源于stack exchange,提问作者IlyaMeer
相关产品推荐
相关产品推荐

