在NestJS项目中用node-soap动态设置SOAP响应的xsi:type属性
问题描述
WSDL类型定义
<s:complexType name="AbstractOperation" abstract="true"> <s:sequence> <s:element minOccurs="1" maxOccurs="1" name="progressive" type="s:int" /> </s:sequence> </s:complexType> <s:complexType name="ConcreteOperation1"> <s:complexContent mixed="false"> <s:extension base="tns:AbstractOperation"> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="identifier" type="s:string" /> </s:sequence> </s:extension> </s:complexContent> </s:complexType> <s:complexType name="ConcreteOperation2"> <s:complexContent mixed="false"> <s:extension base="tns:AbstractOperation"> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="code" type="s:string" /> </s:sequence> </s:extension> </s:complexContent> </s:complexType>
期望的SOAP响应格式
<tns:Operations> <tns:AbstractOperation xsi:type="tns:ConcreteOperation1"> <tns:progressive>1</tns:progressive> <tns:identifier>FP301DW</tns:identifier> </tns:AbstractOperation> <tns:AbstractOperation xsi:type="tns:ConcreteOperation2"> <tns:progressive>2</tns:progressive> <tns:code>AF2F3S</tns:code> </tns:AbstractOperation> </tns:Operations>
当前实现(NestJS + node-soap + Prisma)
从Prisma获取数据后,控制器返回结构如下:
return { Operations: { AbstractOperation: prismaMappedOperationArray, }, }
实际得到的响应
<tns:Operations> <tns:AbstractOperation> <tns:progressive>1</tns:progressive> <tns:identifier>FP301DW</tns:identifier> </tns:AbstractOperation> <tns:AbstractOperation> <tns:progressive>2</tns:progressive> <tns:code>AF2F3S</tns:code> </tns:AbstractOperation> </tns:Operations>
提问
如何根据prismaMappedOperationArray中对象的实例类型(ConcreteOperation1或ConcreteOperation2类),在构造响应时动态添加xsi:type属性?
解决方法
node-soap库支持通过对象的$attributes属性定义XML元素的属性,利用这一点可以动态设置xsi:type:
- 判断对象类型并添加属性
在映射Prisma数据到业务对象时,给每个对象追加$attributes字段,根据对象类型指定对应的xsi:type值:
// 可通过instanceof或自定义标识判断对象类型 const mappedOperations = prismaMappedOperationArray.map(op => { let xsiType; if (op instanceof ConcreteOperation1) { xsiType = 'tns:ConcreteOperation1'; } else if (op instanceof ConcreteOperation2) { xsiType = 'tns:ConcreteOperation2'; } return { ...op, $attributes: { 'xsi:type': xsiType } }; });
- 返回处理后的数组
将修改后的数组作为响应返回:
return { Operations: { AbstractOperation: mappedOperations, }, };
- 命名空间校验
确保SOAP服务器已正确声明xsi命名空间(默认是http://www.w3.org/2001/XMLSchema-instance),node-soap通常会自动处理命名空间映射,若出现异常可在服务器初始化阶段手动配置。
内容的提问来源于stack exchange,提问作者NotSoSnake
相关产品推荐
相关产品推荐

