В качестве продолжения моих мыслей по этому вопросу: Saxon в Java: XSLT для CSV в XML
Согласно ответу Майкла Кея на этот вопрос, я в конечном итоге получил следующий код для применения 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();
Этот код использует s9api в Saxon (у меня версия 9.4 HE). Это позволяет мне установить начальный шаблон и динамически вводить путь к документу, который нужно преобразовать, что позволяет мне преобразовывать файлы, отличные от XML (такие как CSV, в данном конкретном случае).
Однако это несколько сводит на нет мою возможность повторного использования кода.
Поясню: у меня есть метод transformDocument(). Первоначально, до того, как я пытался делать сумасшедшие вещи, такие как преобразование CSV, и работал только с XML, он вызывался обоими моими методами marshalObjectToDocument() и unmarshalDocumentToObject() (есть возможность повторного использования).
Вот сравнение двух направлений, учитывая мир только XML:
unmarshalDocumentToObject()- I start with a file that has the document inside of it.
- Я делаю так:
new StreamSource(new File(documentLocation)) - Этот
StreamSourceможет быть переданtransformDocumentкак "источник" (XsltTransformer.setSource()).
marshalObjectToDocument()- I start with on object of some sort.
- Это маршалируется в гигантскую строку XML.
- Я делаю так:
new StreamSource(new StringReader(giantStringOfXML)) - Этот
StreamSourceможно передатьtransformDocumentв качестве "источника" (XsltTransformer.setSource()).
В случае 1 (unmarshalDocumentToObject()) у меня есть входящий путь к файлу, поэтому я мог бы просто изменить transformDocument(), чтобы взять строку пути к файлу и передать ее, чтобы он мог вручную вставить ее в параметр XSLT. Это будет работать как для XML, так и для простого текста.
В случае 2 (marshalObjectToDocument()) у меня НЕТ пути к файлу. У меня есть объект, который преобразуется в гигантскую строку, содержащую его XML-представление. Я не могу передать строку пути к файлу transformDocument(), потому что у меня нет файла. Теперь я не могу использовать transformDocument(). Возможность повторного использования кода уничтожена.
Моя цель во всем этом состоит в том, чтобы иметь возможность каким-то образом одинаково обрабатывать как XML, так и простые текстовые документы в коде, и иметь возможность повторно использовать мой код для применения XSLT и XSD независимо от того, маршалинг я или демаршалинг. Это донкихотская цель? Обречен ли я на то, чтобы писать разный код для каждого типа документа и направления? Или может кто-то увидеть способ обойти это?