Javascript 如何使用node.js获取SOAP正文?

Javascript 如何使用node.js获取SOAP正文?,javascript,node.js,soap,Javascript,Node.js,Soap,我收到的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

我收到的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>
`;
我希望得到的是不变的内容:

<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包,它基本上可以获取SOAPBODY,而不管使用的前缀是什么。如果前缀发生变化,或者存在可选属性等,上述正则表达式将失败。

您可以使用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);
});

您可以使用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);
});

我使用快速xml解析器来实现这一点,方法是使用以下选项排除名称空间和前缀,并确保属性位于节点“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);
}

希望这有帮助。

我使用快速xml解析器来实现这一点,方法是使用以下选项排除名称空间和前缀,并确保属性位于节点“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);
}

希望这有帮助。

你试过吗?是的,我已经看过这个包裹和其他一些。然而,我并不真正需要服务器。我想说我需要寻找XML解析器来代替。。。仍在调查中。如果您正在从应用程序进行SOAP调用,则它确实具有客户端支持:。如果您刚刚收到SOAP响应,那么您在XML解析器上是正确的。XML解析器的问题是解析所有内容,即SOAP信封和SOAP正文的内容。您尝试过这个吗?是的,我已经看过这个包裹和其他一些。然而,我并不真正需要服务器。我想说我需要寻找XML解析器来代替。。。仍在调查中。如果您正在从应用程序进行SOAP调用,则它确实具有客户端支持:。如果您刚刚收到SOAP响应,那么您在XML解析器上是正确的。XML解析器的问题是解析所有内容,即SOAP信封和SOAP正文的内容。您的解决方案几乎是完美的!我看到的唯一问题是当我向标记添加属性时。例如:soapBodyXML将有一个不需要的父元素:如果我将ignoreAttrs:true添加到选项,那么解析器将删除所有属性,即从父元素中删除我想要的属性,从主体中删除我不想要的所有元素。我注意到这个问题,您肯定不想使用ignoreAttrs,因为您可能希望在SOAP主体中访问某些属性。我确信通过在解析器/生成器中指定选项可以获得所需的行为。我已经修改了您的答案,现在将接受它。这就成功了,我在任何情况下都能得到我所期望的@特里·伦诺克斯谢谢你!我自己花了一些时间寻找一个很好的解决方案。在处理SOAP信封时,XML名称空间会造成很多麻烦。您的解决方案几乎是完美的!我看到的唯一问题是当我向标记添加属性时。例如:soapBodyXML将有一个不需要的父元素:如果我将ignoreAttrs:true添加到选项,那么解析器将删除所有属性,即从父元素中删除我想要的属性,从主体中删除我不想要的所有元素。我注意到这个问题,您肯定不想使用ignoreAttrs,因为您可能希望在SOAP主体中访问某些属性。我确信通过在解析器/生成器中指定选项可以获得所需的行为。我已经修改了您的答案,现在将接受它。这就成功了,我在任何情况下都能得到我所期望的@特里·伦诺克斯谢谢你!我自己花了一些时间寻找一个很好的解决方案。在处理SOAP信封时,XML名称空间会造成很多麻烦。