【问题标题】:Check for XML errors using JavaScript使用 JavaScript 检查 XML 错误
【发布时间】:2011-09-14 02:46:55
【问题描述】:

问题:如何在现代浏览器(IE 除外)中对我的 XML 进行语法检查?

我见过a page on W3Schools,它包含一个 XML 语法检查器。我不知道它是如何工作的,但我想知道如何实现相同的行为。

我已经对此事进行了多次搜索(没有成功),并且我尝试使用 DOM Parser 检查我的 XML 是否“格式正确”(也没有成功)。

var xml = '迦勒'; var parser = new DOMParser(); var doc = parser.parseFromString(xml, 'text/xml');

我希望解析器告诉我有一个 XML 语法错误(即未闭合的 name 标记)。但是,它总是返回一个 XML DOM 对象,就好像根本没有错误一样。

总而言之,我想知道如何使用 JavaScript 自动检查 XML 文档的语法。

附言有什么方法可以根据 DTD 验证 XML 文档(使用 JS,而不是 IE)?

【问题讨论】:

    标签: javascript xml dom


    【解决方案1】:

    编辑:这是一个更简洁的示例,来自MDN:

    var xmlString = '<a id="a"><b id="b">hey!</b></a>';
    var domParser = new DOMParser();
    var dom = domParser.parseFromString(xmlString, 'text/xml');
    
    // print the name of the root element or error message
    dump(dom.documentElement.nodeName == 'parsererror' ? 'error while parsing' : dom.documentElement.nodeName);
    

    【讨论】:

    • 太棒了,这正是我所需要的。谢谢!
    • 函数'checkErrorXML'的定义在哪里??
    • @DerrickRice 来自 MDN 的代码示例是 MIT 许可的(如果在 2010 年之前添加)或公共领域。所以在这种情况下,这不是问题。 ref
    • 是的,这不是很好。字符串“asdk jja sld
    • MDN 不正确,这个答案也是如此。 dom.getElementsByTagName('parsererror') 会更好。 (请参阅此页面上的答案。) 将出现在文档中的某处,但不一定出现在 dom.documentElement。
    【解决方案2】:

    上面的 NoBugs 答案不适用于我当前的 chrome。我建议:

    var sMyString = "<a id=\"a\"><b id=\"b\">hey!<\/b><\/a>";
    var oParser = new DOMParser();
    var oDOM = oParser.parseFromString(sMyString, "text/xml");
    dump(oDOM.getElementsByTagName('parsererror').length ? 
         (new XMLSerializer()).serializeToString(oDOM) : "all good"    
    );
    

    【讨论】:

      【解决方案3】:

      只需F12 进入开发者模式并检查源代码,然后您可以搜索validateXML,您将找到一个非常长的完整XML 检查器参考。

      我正在使用react 和使用DOMParser 的东西将错误消息显示为:

        handleXmlCheck = () => {
          const { fileContent } = this.state;
          const parser = new window.DOMParser();
          const theDom = parser.parseFromString(fileContent, 'application/xml');
          if (theDom.getElementsByTagName('parsererror').length > 0) {
            showErrorMessage(theDom.getElementsByTagName('parsererror')[0].getElementsByTagName('div')[0].innerHTML);
          } else {
            showSuccessMessage('Valid Xml');
          }
        }
      

      【讨论】:

        【解决方案4】:

        javscript 中的基本 xml 验证器。此代码可能对高级 xml 无效,但对基本 xml 无效。

        function xmlValidator(xml){
            // var xml = "<note><to>Tove</to><from>Jani</from><heading>Reminder</heading><body>Don't forget me this weekend!</body></note>";
            while(xml.indexOf('<') != -1){
                var sub = xml.substring(xml.indexOf('<'), xml.indexOf('>')+1);
                var value = xml.substring(xml.indexOf('<')+1, xml.indexOf('>'));
                var endTag = '</'+value+'>';
                if(xml.indexOf(endTag) != -1){
                    // console.log('xml is valid');
                    // break;
                }else{
                    console.log('xml is in invalid');
                    break;
                }
                xml = xml.replace(sub, '');
                xml = xml.replace(endTag, '');
                console.log(xml);
                console.log(sub+' '+value+' '+endTag);
            }
        }
        var xml = "<note><to>Tove</to><from>Jani</from><heading>Reminder</heading><body>Don't forget me this weekend!</body></note>";
        xmlValidator(xml);
        

        【讨论】:

        • 不错的解决方案,但它没有告诉你错误发生的位置,正如你所说的“基本”
        • 谢谢!是的,我只指定xml是有效还是无效。我一定会通过您的建议并进行修改。
        • 如何获取行号?如果无法获得行号,我最好告知发生错误的 XML 标记。请给我一些关于获取行号的建议。
        • 您是否尝试过接受答案中的解决方案,请记住您的解决方案也是有效的,我们可以为您的代码做的增强是通过tag name 而不是行号而不是行号来显示错误根本不显示任何东西,也许简单比这更重要
        【解决方案5】:

        你也可以使用包fast-xml-parser,这个包有一个xml文件的验证检查:

        import { validate, parse } from 'fast-xml-parser';
        
        if( validate(xmlData) === true) {
          var jsonObj = parse(xmlData,options);
        }
        

        【讨论】:

        • 这已被弃用,因为 v4 您现在应该像 XMLValidator.validate(xmlData) 一样导入和使用抽象类 XMLValidator。看看官方documentation。
        【解决方案6】:
        /**
         * Check if the input is a valid XML file.
         * @param xmlStr The input to be parsed.
         * @returns If the input is invalid, this returns an XMLDocument explaining the problem.
         * If the input is valid, this return undefined.
         */
        export function xmlIsInvalid(xmlStr : string) : HTMLElement | undefined {
          const parser = new DOMParser();
          const dom = parser.parseFromString(xmlStr, "application/xml");
          // https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString
          // says that parseFromString() will throw an error if the input is invalid.
          //
          // https://developer.mozilla.org/en-US/docs/Web/Guide/Parsing_and_serializing_XML
          // says dom.documentElement.nodeName == "parsererror" will be true of the input
          // is invalid.
          //
          // Neither of those is true when I tested it in Chrome.  Nothing is thrown.
          // If the input is "" I get:
          // dom.documentElement.nodeName returns "html", 
          // doc.documentElement.firstElementChild.nodeName returns "body" and
          // doc.documentElement.firstElementChild.firstElementChild.nodeName = "parsererror".
          //
          // It seems that the parsererror can move around.  It looks like it's trying to
          // create as much of the XML tree as it can, then it inserts parsererror whenever 
          // and wherever it gets stuck.  It sometimes generates additional XML after the
          // parsererror, so .lastElementChild might not find the problem.
          //
          // In case of an error the <parsererror> element will be an instance of
          // HTMLElement.  A valid XML document can include an element with name name
          // "parsererror", however it will NOT be an instance of HTMLElement.
          //
          // getElementsByTagName('parsererror') might be faster than querySelectorAll().
          for (const element of Array.from(dom.querySelectorAll("parsererror"))) {
            if (element instanceof HTMLElement) {
              // Found the error.
              return element;
            }
          }
          // No errors found.
          return;
        }
        

        (从技术上讲,这就是 TypeScript。删除 : string 和 : HTMLElement | undefined 使其成为 JavaScript。)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-11-04
          • 2021-11-21
          • 2011-06-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-07-27
          相关资源
          最近更新 更多