Saxon в Java: повторное использование кода XSLT

В качестве продолжения моих мыслей по этому вопросу: 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:

  1. unmarshalDocumentToObject()
    • I start with a file that has the document inside of it.
    • Я делаю так: new StreamSource(new File(documentLocation))
    • Этот StreamSource может быть передан transformDocument как "источник" (XsltTransformer.setSource()).
  2. 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 независимо от того, маршалинг я или демаршалинг. Это донкихотская цель? Обречен ли я на то, чтобы писать разный код для каждого типа документа и направления? Или может кто-то увидеть способ обойти это?


person Random Human    schedule 23.05.2012    source источник


Ответы (1)


Конечно, это стандартная и базовая часть разработки программного обеспечения? Здесь у вас есть три фрагмента кода: приложение, которое хочет выполнить преобразование; и механизм XSLT, который выполняет преобразование, и уровень интерфейса, который обеспечивает абстракцию службы, предлагаемой механизмом XSLT, обычно разделяя функциональные возможности на предоставление только того, что нужно приложению, и делая это в более простой форме. Преимущество вашего уровня интерфейса заключается в том, что он снижает сложность API преобразования; недостатком является то, что это также снижает функциональность. Когда вашему приложению начинает требоваться больше функций, которые ранее были скрыты, у вас есть несколько вариантов: вы можете добавить функциональность на уровень интерфейса (в конечном итоге достигнув точки, когда она перестанет добавлять ценность), или вы можете обойти уровень интерфейса для те части приложения, которые не получают от него никакой пользы.

Повторное использование кода зависит от выявления функциональных блоков, которые можно использовать более чем в одном месте. Если разные части вашего приложения выполняют разные задачи, им становится сложнее повторно использовать код. Какие новости?

person Michael Kay    schedule 23.05.2012