Саксонское XSLT-преобразование: как изменить сериализацию пустого тега с <x /> на <x></x>? - PullRequest
0 голосов
/ 14 марта 2010

Я делаю XSLT-преобразование, используя Saxon HE 9.2 , с выходом, который позже распаковывается Castor 1.3.1 . Все это работает с Java на JDK 6 .

Моя XSLT-трансформация выглядит так:

<xsl:transform
version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ns="http://my/own/custom/namespace/for/the/target/document">
<xsl:output method="xml" encoding="UTF-8" indent="no" />
<xsl:template match="/">
  <ns:item>
    <ns:property name="id">
      <xsl:value-of select="/some/complicated/xpath" />
    </ns:property>
    <!-- ... more ... -->
  </ns:item>
</xsl:template>

Итак, дело в том, что если XPath-выражение /some/complicated/xpath оценивается как пустая последовательность, саксонский сериализатор записывает <ns:property/> вместо <ns:property></ns:property>. Это, однако, сбивает с толку демаршаллер Castor, следующий за конвейером и демарширующий вывод преобразования в экземпляры сгенерированных XSD Java-классов.

Итак, мой вопрос: как я могу сказать Saxon-сериализатору выводить пустые теги не как отдельные теги?

Вот то, что я в данный момент выполняю, чтобы выполнить преобразование:

import net.sf.saxon.s9api.*;
import javax.xml.transform.*;
import javax.xml.transform.sax.SAXSource;
// ...

// read data
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
// ... there is some more setting up the xmlReader here ...
InputStream xsltStream = new FileInputStream(xsltFile);
InputStream inputStream = new FileInputStream(inputFile);
Source xsltSource = new SAXSource(xmlReader, new InputSource(xsltStream));
Source inputSource = new SAXSource(xmlReader, new InputSource(inputStream));
XdmNode input = processor.newDocumentBuilder().build(inputSource);

// initialize transformation configuration
Processor processor = new Processor(false);
XsltCompiler compiler = processor.newXsltCompiler();
compiler.setErrorListener(this);
XsltExecutable executable = compiler.compile(xsltSource);
Serializer serializer = new Serializer();
serializer.setOutputProperty(Serializer.Property.METHOD, "xml");
serializer.setOutputProperty(Serializer.Property.INDENT, "no");
serializer.setOutputStream(output);

// execute transformation
XsltTransformer transformer = executable.load();
transformer.setInitialContextNode(input);
transformer.setErrorListener(this);
transformer.setDestination(serializer);
transformer.setSchemaValidationMode(ValidationMode.STRIP);
transformer.transform();

Буду признателен за любую подсказку, указывающую в сторону решения. :-) В случае любой неясности я был бы рад предоставить более подробную информацию.

Ответы [ 3 ]

2 голосов
/ 14 марта 2010

Что касается XML, <x /> и <x></x> - это одно и то же.

Об этом см. XML 1.0 .

Проверьте вашу схему, чтобы убедиться, что <ns:property/> действителен для нее.

1 голос
/ 15 марта 2010

Попробуйте установить метод вывода xhtml вместо xml. Saxon будет использовать сериализатор XHTML, который будет отображать как начальный, так и конечный тег.

Я не верю, что это добавит что-либо дополнительное, связанное с XHTML, к выводу, если вы не добавите дополнительные выходные параметры. В спецификации XSLT 2.0 есть раздел , посвященный сериализации XHTML для справки. Я не уверен, насколько близко саксонцы соответствуют этой области.

1 голос
/ 15 марта 2010

Если вы просто хотите быстро попробовать, если автономные теги действительно вызывают проблему, вы можете вставить (пустой) комментарий в содержимое <ns:property/> (используя <xsl:comment>) - и, возможно, отфильтровать его позже.

...