【问题标题】:How do I access the XML element text using xml2js other than using underscore key?除了使用下划线键之外,如何使用 xml2js 访问 XML 元素文本?
【发布时间】:2025-12-12 13:15:01
【问题描述】:

我有一段 XML 看起来像这样:

<errorMessage>
    <payload encoding="plain">The error message</payload>
</errorMessage>

我使用 xml2js 解析器:

var parser = new xml2js.Parser({
    explicitCharKey: false,
    trim: true,
    explicitRoot: true,
    mergeAttrs: true
});
parser.parseString(myString, function(err, result) {
    var payload = result.errorMessage.payload;
    // how do I access the error message text?
    var errorMessage = payload[0]['_'];
});

我需要访问payload 元素内的The error message 字符串。如果我在包含&lt;payload&gt; 的节点上使用_ 键,那么文本会被正确检索,但使用下划线魔术键看起来很可疑。

这是推荐的方式吗?有没有更清洁的方法?

【问题讨论】:

    标签: javascript xml node.js xml-parsing


    【解决方案1】:

    xml2js options 文档是这样说的:

    attrkey (default: $): Prefix that is used to access the attributes.
    charkey (default: _): Prefix that is used to access the character content.
    

    所以看起来element._ 是您访问element 文本内容的方式。如果您想将此键命名为 _ 以外的其他名称(例如 textContent),您可以这样更改:

    parseString(xml,  {charkey: 'textContent'}, function(err, result) {
       // result.element.textContent will hold the text value of result.element
    });
    

    但是,我还没有找到一种方法使文本内容始终可从_ 键获得。例如,这个:

    xml2js.parseString(
        '<element>1.23</element>', // <-- notice that this has no attributes
        function(err, result) {      
            console.log(JSON.stringify(result));
        }
    );
    

    输出这个:

    {"element":"1.23"}

    但是如果你改变 XML 来添加一个属性,比如&lt;element attr="value"&gt;1.23&lt;/element&gt;,你会得到这个:

    {"element":{"_":"1.23","$":{"attr":"value"}}}

    我需要解析有时有属性但有时没有的 XML 输出。可能有更好的方法,但是当我需要某个元素的文本时,我只需调用getText(element),其中getText 是:

    var getText = function(elt) {
        if (typeof(elt) === 'string') return elt;
        if (typeof(elt) === 'object' && elt.hasOwnProperty('_')) return elt._;
        return ''; // or whatever makes sense for your case
    }
    

    【讨论】:

      【解决方案2】:

      如果您解析带有属性的 XML 文档,您会在 JSON 结果中看到有趣的下划线。就是这样。如果您真的讨厌这样并且不想要文档中的任何属性,请在您的选项块中设置ignoreAttrs : true。然后,您将直接从元素的属性访问元素文本。

      【讨论】:

        【解决方案3】:

        你可以这样做

        const { transform } = require('camaro')
        
        ;(async function() {
            const xml = `
                <errorMessage>
                    <payload encoding="plain">The error message</payload>
                </errorMessage>
            `
            const { errorMessage } = await transform(xml, {
                errorMessage: 'errorMessage/payload'
            })
        
            console.log(errorMessage)
        })()
        
        

        【讨论】:

          【解决方案4】:

          您也可以将mergeAttrs 设置为true 以摆脱所有$ 属性键:

          mergeAttrs(默认值:false):将属性和子元素合并为父属性,而不是从子属性对象中键入属性。如果 ignoreAttrs 为真,则忽略此选项。

          https://www.npmjs.com/package/xml2js#options

          【讨论】: