【问题标题】:How to get SOAP body with node.js?如何使用 node.js 获取 SOAP 正文?
【发布时间】:2018-01-10 10:31:42
【问题描述】:

我收到的 SOAP 消息格式如下:

const soap = `
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
    <env:Header/>
    <env:Body property="def">
        <Root>
            <Abc attr="abc">123456</Abc>
        </Root>
    </env:Body>
</env:Envelope>
`;

我期望得到的是&lt;env:Body&gt;的内容不变:

<Root>
    <Abc attr="abc">123456</Abc>
</Root>

要提取正文,我使用简单的正则表达式:

function getSoapBody(xmlStr) {
    let soapBody = null;
    if (xmlStr) {
        const soapBodyRegex = /<env:Body>([\s\S]*)<\/env:Body>/im;
        const soapBodyRegexMatchResult = xmlStr.match(soapBodyRegex);
        soapBody = soapBodyRegexMatchResult[1];
    }
    return soapBody;
}

但是,使用正则表达式获取 body 当然并不理想。

此外,我不想重新发明轮子,我正在寻找一种解决方案(甚至是 npm 包),无论使用什么前缀(如果前缀更改,上面的正则表达式将失败)或者是否存在,基本上都会 getSoapBody是可选属性等。

【问题讨论】:

  • 你试过这个吗? npmjs.com/package/soap?
  • 是的,我已经查看了这个包以及更多内容。然而,我真的不需要服务器。我会说我需要寻找 XML 解析器...仍在调查。
  • 如果您从您的应用程序进行 SOAP 调用,那么它确实有客户端支持:npmjs.com/package/soap#client。如果您只是收到 SOAP 响应,那么您就在 XML 解析器上。
  • XML 解析器的问题在于解析所有内容,即肥皂信封和肥皂正文的内容。

标签: javascript node.js soap


【解决方案1】:

可以使用xml2js来解析:

var xml2js = require('xml2js');
var builder = new xml2js.Builder();

const soap = `
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
    <env:Header/>
    <env:Body optional="abc">
        <Root>
            <Abc attr="1">123456</Abc>
        </Root>
    </env:Body>
</env:Envelope>
`;

var options = {explicitArray: false, tagNameProcessors: [xml2js.processors.stripPrefix] };

xml2js.parseString(soap, options, (err, result) => {
    if (err) {
        console.log('An error has occurred: ' + err);
        return;
    } 

    // Get the soap body object
    var soapBody = result.Envelope.Body;

    // Remove optional attribute(s) from <Body> element.
    if (soapBody.$) {
        delete soapBody.$;
    }

    // Get the body XML if needed
    var soapBodyXML = builder.buildObject(soapBody);

    console.log(soapBodyXML);
});

【讨论】:

  • 您的解决方案几乎完美!我看到的唯一问题是当我向&lt;Body&gt; 标签添加属性时。例如:&lt;soapenv:Body attr="abc"&gt; 然后soapBodyXML 将有一个不需要的父元素:&lt;root attr="abc"&gt;
  • 我注意到了这个问题,您肯定不想使用 ignoreAttrs,因为您可能希望在 SOAP 主体中访问一些属性。我确信通过在解析器/构建器中指定选项可以获得所需的行为。
  • 我已修改您的答案,现在将接受。这就是诀窍,我在所有情况下都能得到我所期望的。 @Terry Lennox 谢谢
  • 太棒了!我花了一些时间自己寻找一个很好的解决方案。在处理 SOAP 信封时,XML 命名空间会引起很多麻烦。
【解决方案2】:

我使用 fast-xml-parser (https://www.npmjs.com/package/fast-xml-parser/v/2.9.0) 来实现这一点,方法是使用以下选项排除命名空间和前缀并确保属性位于节点“attr”下:

async function stripBodyFromSoapEnvelope(inputBody){
    const xmlParser = require('fast-xml-parser');        
    let options = {
            attributeNamePrefix : '',
            attrNodeName: 'attr',
            ignoreNameSpace: true,
            ignoreAttributes: false
        };
    const soapenv = xmlParser.parse(inputBody,options);
    return(soapenv.Envelope.Body);
}

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-10
    • 1970-01-01
    • 1970-01-01
    • 2019-08-10
    • 2013-09-13
    • 1970-01-01
    • 2012-01-29
    • 1970-01-01
    相关资源
    最近更新 更多