XSLT无法删除属性值前后的换行符



我正在尝试将带有Saxon 9.9HE的XSLT3.0的XML模式转换为JSON。转型正在发挥作用。但是,当我输出属性的值时,它在名称前后都带有换行符。XSD片段如下:

<group name="imapAttachmentDownloaderGroup">
<annotation>
<documentation>
Configuration block definitions for IMAP attachment downloader delegate. It contains all the configuration
block definitions that are required to configure the delegate successfully.
</documentation>
</annotation>
<sequence>
<element name="IMAPConnectorConfig">
<complexType>
<attribute name="imapHost" use="required" type="string">
<annotation>
<documentation>
This configuration block deals with the IMAP server name or IP address to where the 
connection is to be made to download the attachments.
Example: "outlook.office365.com" or "40.100.137.66"
</documentation>
</annotation>
</attribute>
<attribute name="imapPort" use="required" type="int">
<annotation>
<documentation>
The port to use to connect to the server, defaults to 993.
Example: "993"
</documentation>
</annotation>
</attribute>
....

SXL如下:

<?xml version="1.0" encoding="UTF-8"?>
<stylesheet version="3.0" 
xmlns="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://www.proviseconsulting.com/ProcessConfig"
xmlns:saxon="http://saxon.sf.net/"
xsi:schemaLocation="http://www.w3.org/1999/XSL/Transform 
https://www.w3.org/2007/schema-for-xslt20.xsd">
<mode on-no-match="shallow-skip"/>
<output method="text" encoding="utf-8" indent="no" media-type="application/json" normalization-form="true"/>
<strip-space elements="*" />
<!-- <template match="text()|@*"/> -->
<param name="delegateGroupName" required="yes"/>
<template match="/child::xsi:schema/child::xsi:group[attribute::name=$delegateGroupName]">
<variable name="xx" select="attribute::name"/>
{'groupName':'<value-of select="normalize-space($xx)"/>'
<for-each select="child::xsi:sequence/child::xsi:element">
,'<value-of select="attribute::name"/>':{
<for-each select="child::xsi:complexType/child::xsi:attribute">
<choose>
<when test="position()=last()">'name':'<value-of select="attribute::name"/>'</when>
<otherwise>'name':'<value-of select="attribute::name"/>',</otherwise>
</choose>
</for-each>
<for-each select="child::xsi:complexType/child::xsi:attributeGroup">
<value-of select="attribute::ref"/>
</for-each>
}
</for-each>
}
<!-- <apply-templates select="attribute::name"/> -->
</template>

输出为:

{'groupName':'
imapAttachmentDownloaderGroup
'
,    '
IMAPConnectorConfig
':{
'name':'
imapHost
',
'name':'
imapPort
',
'name':'
sslEnabled
',
'name':'
startTLSEnabled
',
'name':'
imapUser
',
'name':'
imapPassword
',
'name':'
credentialId

我已经尝试了在将其分配给变量的帖子中可以找到的所有机制,normalize space,normalize pace with string((with data((。似乎什么都不起作用。如有任何帮助,我们将不胜感激。

===包括完整的示例===

XSL(删除了所有注释和其他元素(:

<?xml version="1.0" encoding="UTF-8"?>
<stylesheet version="3.0" 
xmlns="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://www.proviseconsulting.com/ProcessConfig"
xmlns:saxon="http://saxon.sf.net/"
xsi:schemaLocation="http://www.w3.org/1999/XSL/Transform 
https://www.w3.org/2007/schema-for-xslt20.xsd">
<mode on-no-match="shallow-skip"/>
<output method="text" encoding="utf-8" indent="no" media-type="application/json" normalization-form="true"/>
<strip-space elements="*" />
<param name="delegateGroupName" required="yes"/>
<template match="/child::xsi:schema/child::xsi:group[attribute::name=$delegateGroupName]">
<text>{"groupName":"</text><value-of select="attribute::name/normalize-space()"/><text>"}</text>
</template>

===输出===

{"groupName":"
imapAttachmentDownloaderGroup
"}

输入XSD保持不变。Java代码如下:

String xsdFilePath="file:///D:/workspaces/mtplatform/PlatformManual_V1/PlatformManual/ProcessConfiguration/ProcessConfiguration.xsd";
String xslFilePath="file:///D:/workspaces/mtplatform/PlatformManual_V1/PlatformManual/ProcessConfiguration/ProcessConfiguration.xsl";
Processor processor=new Processor(false);
XdmNode node=processor.newDocumentBuilder().build(new File(new URI(xsdFilePath)));
XsltCompiler xsltCompiler=processor.newXsltCompiler();
//xsltCompiler.setParameter(new QName("delegateGroupName"), XdmValue.makeValue("imapAttachmentDownloaderGroup"));
StreamSource xsdSource=new StreamSource(new FileInputStream(new File(new URI(xsdFilePath))));
StreamSource xslSource=new StreamSource(new FileInputStream(new File(new URI(xslFilePath))));
XsltExecutable compiledXSL=xsltCompiler.compile(xslSource);
Xslt30Transformer xslTransformer=compiledXSL.load30();
HashMap<QName, XdmValue> parameterMap=new HashMap<>();
parameterMap.put(new QName("delegateGroupName"), XdmValue.makeValue("imapAttachmentDownloaderGroup"));
xslTransformer.setStylesheetParameters(parameterMap);
XdmValue output=xslTransformer.applyTemplates(node);
System.out.println(output.toString());

通常,要控制文本输出,可以使用xsl:text元素https://www.w3.org/TR/xslt-30/#xsl-形式的文本

<for-each select="child::xsi:sequence/child::xsi:element">
<text>,'</text>
<value-of select="attribute::name"/>
<text>':{</text>

此外,如果您使用Xslt30Transformer,并且想要以文本形式(如JSON(的序列化结果,其中格式由XSLT中的xsl:output定义,那么您应该使用applyTemplates的重载,从而允许使用Serializer作为Destination,即。http://saxonica.com/html/documentation/javadoc/net/sf/saxon/s9api/Xslt30Transformer.html#applyTemplates-net.sf.saxon.s9api.XdmValue-net.sfsaxon.s9api.Destination-使用Xslt30Transformer创建的Serializer(http://saxonica.com/html/documentation/javadoc/net/sf/saxon/s9api/Xslt30Transformer.html#newSerializer-java.io.OutputStream-(,因此在使用System.out测试结果的简单情况下,您将使用

Serializer serializer =  xslTransformer.newSerializer(System.out);
xslTransformer.applyTemplates(node, serializer);

在您的Java案例中,您已经使用重载创建了XdmValue,请注意它的文档http://saxonica.com/html/documentation/javadoc/net/sf/saxon/s9api/Xslt30Transformer.html#applyTemplates-net.sf.saxon.s9api.XdmValue-表示返回

将模板应用于所提供的选择值的原始结果,而不包装在文档节点中或序列化结果

根据您的评论,如果您有一个XdmValue并希望以可控的方式对其进行序列化,那么最好使用根据需要设置的SerializerserializeXdmValue方法,而不是简单地在XdmValue上调用toString

最新更新