开发者

Saxon XSLT-Transformation: How to change serialization of an empty tag from <x/> to <x></x>?

I do some XSLT-Transformation using Saxon HE 9.2 with the output later being unmarshalled by Castor 1.3.1. The whole thing runs with Java at the JDK 6.

My XSLT-Transformation looks like this:

<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>

So the thing is: if the XPath-expression /some/complicated/xpath evaluates to an empty sequence, the Saxon serializer writes <ns:property/> instead of <ns:property></ns:property>. This, however, confuses the Castor unmarshaller, which is next in the pipeline and which unmarshals the output of the transformation to instances of XSD-generated Java-classes.

So my question is: How can I tell the Saxon-serializer to output empty tags not as standalone tags?

Here is what I am proximately currently doing to execute the transformation:

开发者_如何学运维
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();

I'd appreciate any hint pointing in the direction of a solution. :-) In case of any unclarity I'd be happy to give more details.


As far as XML is concerned <x /> and <x></x> are the same thing.

See the XML 1.0 spec about this.

Check your schema to make sure the <ns:property/> is valid for it.


If you just want to quickly try, if the standalone tags really cause the problem, you could insert an (empty) comment in the content of <ns:property/> (using <xsl:comment>) - and maybe filter that out later.


Try setting the output method to xhtml instead of xml. Saxon will use the XHTML serializer which will render both the start and end tag.

I don't believe it will add anything additional related to XHTML to the output unless you add addition output parameters. There is a section in the XSLT 2.0 spec dedicated to XHTML serialization for reference. I'm not sure how closely Saxon conforms in this area.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜