如何在Apigee X的XSL转换后移除XML声明标签
问题:Apigee X中XSL转换后SOAP Body出现XML声明标签导致服务报错
场景说明
用户发送包含对象数组的JSON payload,通过Apigee X的JSONtoXML和XSLT政策转换为SOAP服务所需XML格式,但转换后SOAP Body中出现<?xml version="1.0" encoding="UTF-8"?>声明标签,SOAP服务不接受该标签。
相关配置及输出
用户JSON Payload
{"putPlcExamScore": {"Student": [{"ID": "Professor","Form": "S","GradePoints": "123"},{"ID": "Snape","Form": "7","GradePoints": "322"}]}}
JSONtoXML 政策配置
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <JSONToXML continueOnError="false" enabled="true" name="JX-JsontoXML"> <DisplayName>JX-JsontoXML</DisplayName> <Properties/> <Options> <NullValue>NULL</NullValue> <NamespaceBlockName>#namespaces</NamespaceBlockName> <DefaultNamespaceNodeName>$default</DefaultNamespaceNodeName> <NamespaceSeparator>:</NamespaceSeparator> <TextNodeName>#text</TextNodeName> <AttributeBlockName>#attrs</AttributeBlockName> <AttributePrefix>@</AttributePrefix> <InvalidCharsReplacement>_</InvalidCharsReplacement> <ObjectRootElementName>Root</ObjectRootElementName> <ArrayRootElementName>Array</ArrayRootElementName> <ArrayItemElementName>Item</ArrayItemElementName> </Options> <OutputVariable>request</OutputVariable> <Source>request</Source> </JSONToXML>
XSLT Transformation 政策配置
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <XSL continueOnError="false" enabled="true" name="XSLT-ConvertPayload"> <DisplayName>XSLT-ConvertPayload</DisplayName> <Properties/> <Source>request</Source> <ResourceURL>xsl://PlacementScores.xsl</ResourceURL> <Parameters ignoreUnresolvedVariables="true"/> <OutputVariable>ps_modifiedpayload</OutputVariable> </XSL>
XSL资源配置
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="/"> <put:putPlcExamScore xmlns:put="http://something.v1"> <xsl:for-each-group select="//Student" group-by="ID"> <xsl:for-each select="current-group()"> <put:Student> <put:ID> <xsl:value-of select="ID"/> </put:ID> <put:Form> <xsl:value-of select="Form"/> </put:Form> <put:GradePoints> <xsl:value-of select="GradePoints"/> </put:GradePoints> </put:Student> </xsl:for-each> </xsl:for-each-group> </put:putPlcExamScore> </xsl:template> </xsl:stylesheet>
AssignMessage政策片段
<soapenv:Body> {ps_modifiedpayload} </soapenv:Body>
问题输出(Trace中结果)
<soapenv:Body> <?xml version="1.0" encoding="UTF-8"?> <put:putPlcExamScore xmlns:put="something.v1"> <put:Student> <put:ID>Professor</put:ID> <put:Form>S</put:Form> <put:GradePoints>123</put:GradePoints> </put:Student> <put:Student> <put:ID>Snape</put:ID> <put:Form>7</put:Form> <put:GradePoints>322</put:GradePoints> </put:Student> </put:putPlcExamScore> </soapenv:Body>
解决方案
方法1:修改XSL资源的输出配置(推荐)
在XSL资源的<xsl:output>标签中添加omit-xml-declaration="yes"属性,直接让XSL转换时不生成XML声明标签。修改后的XSL资源如下:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 添加omit-xml-declaration="yes"移除XML声明 --> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="/"> <put:putPlcExamScore xmlns:put="http://something.v1"> <xsl:for-each-group select="//Student" group-by="ID"> <xsl:for-each select="current-group()"> <put:Student> <put:ID> <xsl:value-of select="ID"/> </put:ID> <put:Form> <xsl:value-of select="Form"/> </put:Form> <put:GradePoints> <xsl:value-of select="GradePoints"/> </put:GradePoints> </put:Student> </xsl:for-each> </xsl:for-each-group> </put:putPlcExamScore> </xsl:template> </xsl:stylesheet>
方法2:使用Apigee JavaScript政策移除声明标签
如果无法修改XSL资源,可以添加一个JavaScript政策,对ps_modifiedpayload变量进行字符串替换,移除XML声明:
var payload = context.getVariable('ps_modifiedpayload'); // 移除XML声明标签 var cleanedPayload = payload.replace(/<\?xml[^>]+>/g, ''); context.setVariable('ps_modifiedpayload', cleanedPayload);
然后在AssignMessage政策之前执行这个JavaScript政策即可。
内容的提问来源于stack exchange,提问作者Kranthi Bandaru
相关产品推荐
相关产品推荐

