作为我从这个问题的思维模式的延续:Java中的撒克逊人:XSLT for CSV to XML
根据 Michael Kay 对该问题的回答,我最终得到了以下代码,用于将 XSLT 应用于文档:
Processor processor = new Processor(false);
StringWriter stringWriter = new StringWriter();
Serializer serializer = new Serializer(stringWriter);
XsltCompiler compiler = processor.newXsltCompiler();
XsltExecutable executable = compiler.compile(new StreamSource(new File(transformLocation)));
XsltTransformer transformer = executable.load();
transformer.setInitialTemplate(new QName("main"));
transformer.setParameter(new QName("filePath"), new XdmAtomicValue("location/of/Test.csv"));
transformer.setDestination(serializer);
transformer.transform();
String transformedDocument = stringWriter.toString().trim();
此代码使用了 Saxon 中的 s9api(我使用的是 9.4 HE 版本)。它允许我设置初始模板并动态注入要转换的文档的路径,这允许我转换非 XML 文件(例如 CSV,在这种特殊情况下)。
但是,这有点抹杀了我的代码可重用性。
让我解释一下:我有一个transformDocument()
方法。最初,在我尝试做一些疯狂的事情(如转换 CSV 并且只使用 XML)之前,我的方法marshalObjectToDocument()
和unmarshalDocumentToObject()
方法都调用了它(有可重用性)。
下面是给定一个只有 XML 的世界的两个方向的比较:
unmarshalDocumentToObject()
- 我从一个包含文档的文件开始。
- 我这样做:
new StreamSource(new File(documentLocation))
- 这
StreamSource
可以transformDocument
作为“源”(XsltTransformer.setSource()
) 传递给。
marshalObjectToDocument()
- 我从某种对象开始。
- 这被编组为一个巨大的 XML 字符串。
- 我这样做:
new StreamSource(new StringReader(giantStringOfXML))
- 这
StreamSource
可以transformDocument
作为“源”(XsltTransformer.setSource()
) 传递给。
在情况 1 ( unmarshalDocumentToObject()
) 我有一个文件路径进入,所以我可以更改transformDocument()
为获取文件路径字符串并将其传递给它,以便它可以手动将其注入 XSLT 参数。这适用于 XML 和纯文本。
在情况 2 ( marshalObjectToDocument()
) 我没有文件路径。我有一个对象,它被转换为一个包含其 XML 表示的巨型字符串。我无法将文件路径字符串传递给,transformDocument()
因为我没有文件。现在我不能使用transformDocument()
. 代码可重用性被破坏。
在所有这一切中,我的目标是能够以某种方式在代码中以相同的方式处理 XML 和纯文本文档,并且能够重用我的代码来应用 XSLT 和 XSD,无论我是在编组还是解组。这是一个不切实际的目标吗?我是否注定要为每种文档类型和方向编写不同的代码?或者有人可以解决这个问题吗?