【问题标题】:XML single node parsing with peg.js使用 peg.js 解析 XML 单节点
【发布时间】:2014-12-08 14:32:44
【问题描述】:

给定输入<outer> Content <inner> Inner <single/> </inner> </outer>

我将如何编写语法来解析 <single> 节点以及具有匹配关闭节点的节点?

这是我目前的语法,取自here

Content =
  (Element / Text)*

Element =
  startTag:StartTag content:Content endTag:EndTag {
    if (startTag != endTag) {
      throw new Error(
        "Expected </" + startTag + "> but </" + endTag + "> found."
      );
    }

    return {
      name:    startTag,
      content: content
    };
  }

StartTag =
  "<" name:TagName ">" { return name; }

EndTag =
  "</" name:TagName ">" { return name; }

TagName = chars:[a-z]+ { return chars.join(""); }
Text    = chars:[^<]+  { return chars.join(""); }

这仅适用于具有关闭节点的节点。

我认为问题在于文本规则。所以我一直在尝试改变它以包含一个负面的前瞻,比如:

Text    = chars:(!EndTag .)* EndTag { return chars.join(""); }

但这还没有取得任何成功。

有什么想法吗?

【问题讨论】:

  • 嘎——你改变了我的标签分隔符,你这个傻瓜! :)
  • 糟糕,抱歉!这首先是一个错字。但它似乎仍然不起作用? peg.arcanis.fr/fwvT9/1

标签: javascript xml peg


【解决方案1】:

我这样做的方式是让 Element 匹配“sTag”或“selfTag”;如果匹配“selfTag”,则没有“Content”或“endTag”:

Content =
  (Element / Text)*

Element =
  startTag:sTag content:Content endTag:eTag {
    if (startTag != endTag) {
      throw new Error(
        "Expected </" + startTag + "> but </" + endTag + "> found."
      );
    }

    return {
      name:    startTag,
      content: content
    };
  }
  / startTag:selfTag {
        return startTag;
    }

sTag =
  "<" name:TagName ">" { return name; }

selfTag =
  "<" name:TagName "/>" { return name; }

eTag =
  "</" name:TagName ">" { return name; }

TagName = chars:[a-z-]+ { return chars.join(""); }
Text    = chars:[^<]+  { return chars.join(""); }

请注意,此答案要求您使用 &lt;single/&gt; 而不是 &lt;single&gt;(即 / 是必需的);这是向 PEG 解析器发出悬空开始标记和“自闭合标记”之间区别的最简单方法。

【讨论】:

  • 我得到一个错误:Expected &lt;/single&gt; but &lt;/inner&gt; found. 它在没有&lt;single&gt; 节点的情况下工作。 peg.arcanis.fr/fwvT9/1
  • 啊,我现在看到了&lt;single/&gt; 部分。现在可以了。你认为没有结束 / 就不可能做到吗?
  • 这将更加困难 - 您必须仔细考虑如何区分未关闭的开始标签(应该正确地引发错误)和不需要关闭的标签。
  • 我将尝试让它在没有额外的/ 的情况下工作。如果没有骰子,我会回来并更改我的问题以使用&lt;single/&gt; 并将您的答案标记为正确。谢谢。
  • This SO 问题和答案可能对您有所帮助,因为您将要处理的是“模棱两可的语法”
猜你喜欢
  • 1970-01-01
  • 2011-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-21
  • 2012-06-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多