You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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:

  1. 判断对象类型并添加属性
    在映射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
        }
    };
});
  1. 返回处理后的数组
    将修改后的数组作为响应返回:
return {
    Operations: {
        AbstractOperation: mappedOperations,
    },
};
  1. 命名空间校验
    确保SOAP服务器已正确声明xsi命名空间(默认是http://www.w3.org/2001/XMLSchema-instance),node-soap通常会自动处理命名空间映射,若出现异常可在服务器初始化阶段手动配置。

内容的提问来源于stack exchange,提问作者NotSoSnake

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 02:57:09