Saxon XSLT-Transformation:如何从更改空标签的序列化到 ?
我使用 Saxon HE 9.2 进行一些 XSLT 转换,随后由 Castor 1.3.1 对输出进行解组。整个过程在 JDK 6 上使用 Java 运行。
我的 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
计算结果为空序列,则 Saxon 序列化程序将写入
而不是
。然而,这让 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();
有任何指向解决方案方向的提示,我将不胜感激。 :-) 如果有任何不清楚的地方,我很乐意提供更多细节。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
就 XML 而言,
和
是同一件事。有关此内容,请参阅 XML 1.0 规范。
检查您的架构以确保
对其有效。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.如果您只是想快速尝试,如果独立标签确实导致了问题,您可以在
的内容中插入(空)注释(使用< ;xsl:comment>) - 也许稍后将其过滤掉。
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.尝试将输出方法设置为 xhtml 而不是 xml。 Saxon 将使用 XHTML 序列化器来呈现开始和结束标记。
我不相信它会在输出中添加任何与 XHTML 相关的附加内容,除非您添加附加输出参数。 XSLT 2.0 规范中有一个部分专门用于XHTML 序列化供参考。我不确定撒克逊人在这方面的符合程度如何。
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.