我有将由表单填充的值的 XML 列表。基于特定元素的值,在本例中为Type,我需要动态构造一个 SOAP 请求。将仅使用 Source XML 中的某些元素,具体取决于Type。此外,我需要为 SOAP 主体中的每个元素添加一个名称空间前缀,这些元素在源 XML 中不存在或以任何方式引用。
给定以下格式的 XML 输入:
<User>
<Action>Update</Action>
<Id>123-45-5678</Id>
<Type>Student</Type>
<Validate>true</Validate>
<Grade>11</Grade>
<Classroom/>
<UserName/>
<Password/>
</User>
如果我应用以下转换:
<xsl:stylesheet version="1.0" xmlns:ztx="http://tempuri.org/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:variable name="Action" select="/User/Action"/>
<xsl:variable name="Id" select="/User/Id"/>
<xsl:variable name="Type" select="/User/Type"/>
<xsl:variable name="Method" select="concat('ztx:', $Action, $Type)"/>
<xsl:template match="/">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<xsl:element name="{$Method}">
<xsl:if test="$Action != 'Create'">
<xsl:copy-of select="/User/Id"/>
</xsl:if>
<xsl:if test="$Action != 'Delete'">
<xsl:choose>
<xsl:when test="$Type = 'Teacher'">
<xsl:copy-of select="/User/Classroom"/>
</xsl:when>
<xsl:when test="$Type = 'Student'">
<xsl:copy-of select="/User/Grade"/>
</xsl:when>
<xsl:when test="$Type = 'Administrator'">
<xsl:copy-of select="/User/UserName"/>
<xsl:copy-of select="/User/Password"/>
</xsl:when>
</xsl:choose>
<xsl:copy-of select="/User/Validate"/>
</xsl:if>
</xsl:element>
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
</xsl:stylesheet>
我得到以下输出:
<soapenv:Envelope xmlns:ztx="http://tempuri.org/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<ztx:UpdateStudent>
<Id>123-45-5678</Id>
<Grade>11</Grade>
<Validate>true</Validate>
</ztx:UpdateStudent>
</soapenv:Body>
</soapenv:Envelope>
然而,我想要的输出是:
<soapenv:Envelope xmlns:ztx="http://tempuri.org/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<ztx:UpdateStudent>
<ztx:Id>123-45-5678</ztx:Id>
<ztx:Grade>11</ztx:Grade>
<ztx:Validate>true</ztx:Validate>
</ztx:UpdateStudent>
</soapenv:Body>
</soapenv:Envelope>
如果可能的话,我想优雅地做到这一点,并且在一次转换中。寻找一种通用方式,可能使用另一个模板,只处理 SOAP 主体中的每个元素并添加名称空间,而不是单独对它们进行硬编码。
注意:我仅限于 XSLT 1.0
谢谢!