【问题标题】:Remove <> symbols from CDATA XML tag using regex使用正则表达式从 CDATA XML 标记中删除 <> 符号
【发布时间】:2021-09-05 20:18:51
【问题描述】:

假设我有一个这样的 XML 文档:

<records>
    <record>
        <name>Jon</name>
        <surname>Doe</surname>
        <dob>2001-02-01</dob>
        <comment>
            <![CDATA[[ Patient with > 2 and < 5 siblings]]]>
        </comment>
    </record>
    <record>
        <name>Jane</name>
        <surname>Doe</surname>
        <dob>2001-02-01</dob>
        <comment>
            <![CDATA[[ Patient with > 2 siblings ]]]>
        </comment>
    </record>
</records>

我需要使用 xml2js 将此文档转换为 JSON 对象,但我需要删除 &lt;&gt; 符号以避免破坏 JSON 转换过程。

我的尝试

由于我了解我需要在将 XML 字符串传递给 xml2js 解析器之前删除这些符号,因此我尝试了以下情况中描述的解决方案的变体:

我成功匹配了CDATA 标记的全部内容,但无法匹配我需要删除的特定字符。这必须在单个 regex 中完成,因此我可以将其传递给 XML 到 JSON 解析器。

任何帮助或指针将不胜感激。提前致谢。

其他信息

添加此问题是因为该问题因缺乏研究证据而被否决。

我尝试修改在我提到的参考文献之一中找到的正则表达式规则。这是规则。

\[CDATA\[(.*?)\]\]>`

这匹配 CDATA 标记的全部内容。这很有帮助,但我需要替换/删除 CDATA 标记的内容。这是它在正则表达式编辑器上的外观。

然后我继续修改规则以匹配&lt;&gt; 这是我尝试过的规则。

\[CDATA\[(.*?)[<>]*\]\]>

此规则匹配以下内容(不仅仅是 符号)。

    [ Patient with > 2 and < 5 siblings]

这是它在正则表达式编辑器上的外观。

我希望这能让我更清楚地了解我想要完成的工作。

编辑 2:

这是代码触发的错误。相关错误信息为invalid closing tag

这是错误跟踪中引用的import.js 的第 38 行。

const jsonXml = await parseStringPromise(xml).then((res) => res);

此行使用xml2js 解析 XML 文档并将其转换为 JSON 对象。因为 CTAG 包含 &lt;&gt; 符号,我假设解析器认为它是未正确关闭的 XML 标记的一部分。

【问题讨论】:

  • 您的转换以什么方式中断? comment: ["\n [ Patient with &gt; 2 and &lt; 5 siblings]\n "]不是你期待的内容吗?
  • 嘿,我正在编辑问题以展示我的尝试。我考虑了两个选项:1)一起删除 符号 2)将它们转换为 HTML 实体 XM 到 JSON 的转换中断,因为 XML 标记使用这些符号。我正在寻找处理这些案件的方法。
  • 您是否尝试使用正则表达式直接处理 XML 文档?如果是这样,为什么这个标签是xslt? --附言不要尝试使用正则表达式直接处理 XML 文档 - 请参阅此处原因:stackoverflow.com/a/1732454
  • 请展示您使用该库的代码以及您获得的结果与您想要的结果的对比,或者说明“转换中断”的方式以及您遇到的错误。
  • 你好@michael.hor257k。我将问题标记为 XSL,因为此 XML 文件将由 XSL 样式表设置样式。但是,问题不在于 XSL 相关的道歉。 Martin,将在几分钟内使用请求信息编辑问题。

标签: regex xml xml2js


【解决方案1】:

我无法重现解析问题(使用当前版本的库,0.4.23):

var xml2js = require("xml2js")

var xml = `<records>
    <record>
        <name>Jon</name>
        <surname>Doe</surname>
        <dob>2001-02-01</dob>
        <comment>
            <![CDATA[[ Patient with > 2 and < 5 siblings]]]>
        </comment>
    </record>
    <record>
        <name>Jane</name>
        <surname>Doe</surname>
        <dob>2001-02-01</dob>
        <comment>
            <![CDATA[[ Patient with > 2 siblings ]]]>
        </comment>
    </record>
</records>`;

const jsResult = await xml2js.parseStringPromise(xml).then((res) => res);

const jsonResult = JSON.stringify(jsResult);

console.dir(jsonResult);

这给了

{"records":{"record":[{"name":["Jon"],"surname":["Doe"],"dob":["2001-02-01"],"comment":["\n            [ Patient with > 2 and < 5 siblings]\n        "]},{"name":["Jane"],"surname":["Doe"],"dob":["2001-02-01"],"comment":["\n            [ Patient with > 2 siblings ]\n        "]}]}}

在 jsonlint.com 上验证并格式化为

{
    "records": {
        "record": [{
            "name": ["Jon"],
            "surname": ["Doe"],
            "dob": ["2001-02-01"],
            "comment": ["\n            [ Patient with > 2 and < 5 siblings]\n        "]
        }, {
            "name": ["Jane"],
            "surname": ["Doe"],
            "dob": ["2001-02-01"],
            "comment": ["\n            [ Patient with > 2 siblings ]\n        "]
        }]
    }
}

或者您也可以使用const jsonResult = JSON.stringify(jsResult, null, 4); 来提供可读的输出

{
    "records": {
        "record": [{
            "name": ["Jon"],
            "surname": ["Doe"],
            "dob": ["2001-02-01"],
            "comment": ["\n            [ Patient with > 2 and < 5 siblings]\n        "]
        }, {
            "name": ["Jane"],
            "surname": ["Doe"],
            "dob": ["2001-02-01"],
            "comment": ["\n            [ Patient with > 2 siblings ]\n        "]
        }]
    }
}

【讨论】:

  • 你好,马丁。您之前提到过,这个问题更多地与格式错误的 XML 有关,而不是与库有关。给出的示例是我创建的一个人为的案例,因为出于隐私考虑,我无法放置整个 XML 消息。同样,xml2js 库按预期处理这种情况。这不是图书馆的问题。
【解决方案2】:

在 JavaScript 中,由于它是您用于编码的语言,因此您可以使用

const text = `<comment>
   <![CDATA[[ Patient with > 2 and < 5 siblings]]]>
</comment>`
const re = /\[CDATA\[\[[^]*?]]>/g
console.log( text.replace(re, (x) => x.replace(/[<>]/g, '')) )

\[CDATA\[\[[^]*?]]&gt; 模式(参见its demo)匹配所有CDATA 块,即使它们跨越多行,因为

  • \[CDATA\[\[ 匹配 [CDATA[[ 子字符串
  • [^]*? 尽可能少地匹配零个或多个字符
  • ]]&gt; 匹配 ]]&gt;

然后,一旦找到匹配项,所有&lt;&gt; 将从这些与x.replace(/[&lt;&gt;]/g, '') 匹配的文本中删除。

【讨论】:

    【解决方案3】:

    我正在使用 Wiktor Stribiżew 提供问题的答案,以防万一这有助于遇到类似问题的任何人。

    (?<=<!\[CDATA\[\[(?:(?!<!\[CDATA\[\[|]]>).)*)[<>]
    

    谢谢维克托

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-11
      • 1970-01-01
      • 1970-01-01
      • 2016-01-24
      相关资源
      最近更新 更多