【问题标题】:how to find offending line when using XmlSlurper使用 XmlSlurper 时如何找到违规行
【发布时间】:2012-01-04 23:19:48
【问题描述】:

我正在使用 XmlSlurper 解析一个脏的 html 页面,我收到以下错误:

ERROR org.xml.sax.SAXParseException: Element type "scr" must be followed by either attribute specifications, ">" or "/>".
    at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
    at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
        ...
[Fatal Error] :1157:22: Element type "scr" must be followed by either attribute specifications, ">" or "/>".

现在,我有 html 供我输入并在此之前打印它。如果我打开它并尝试转到错误中提到的行 1157,那里没有“src”(但文件中有数百个这样的字符串)。所以我猜想插入一些额外的东西(可能是<script> 或类似的东西)会改变行号。

有没有什么好的方法可以准确地找到有问题的行或 html 片段?

【问题讨论】:

  • 错误提到“scr”,你是说你找不到“src”。这是一个错字,还是您在文档中搜索错误的内容?
  • 在找到 NekoHTML 之前,我也在使用 TagSoup。我不记得确切的原因,但 TagSoup 只是没有解决。您可以在此处查看如何使用 NekoHTML 的示例 - stackoverflow.com/questions/9260461/…

标签: html groovy xerces xmlslurper


【解决方案1】:

您使用的是哪个 SAXParser? HTML 不是严格的 XML,因此将 XMLSlurper 与默认解析器一起使用可能会导致持续错误。

在 Google 上粗略搜索“Groovy html slurper”后,我找到了 HTML Scraping With Groovy,它指向一个名为 TagSoup 的 SaxParser。

试一试,看看它是否解析脏页。

【讨论】:

  • 谢谢,我已经尝试过Tagsoup,但一无所获。直到几天前,当我摄取的页面发生变化时,我的代码在默认解析器的 XmlSlurper 上运行良好。在使用 XmlSlurper 之前,我自己通过代码修复了有问题的东西,问题是我现在找不到有问题的东西......
  • 我接受了这个,尽管它不是我问题的答案。但我又给了 Tagsoup 一次,这次效果很好
【解决方案2】:

您可以为每个元素添加一个名为 _lineNum 的属性,然后可以使用该属性。

import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.ext.Attributes2Impl;
import javax.xml.parsers.ParserConfigurationException;

class MySlurper extends XmlSlurper {    
    public static final String LINE_NUM_ATTR = "_srmLineNum"
    Locator locator

    public MySlurper() throws ParserConfigurationException, SAXException {
        super();
    }

    @Override
    public void setDocumentLocator(Locator locator) {
        this.locator = locator;
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
        Attributes2Impl newAttrs = new Attributes2Impl(attrs);        
        newAttrs.addAttribute(uri, LINE_NUM_ATTR, LINE_NUM_ATTR, "ENTITY", "" + locator.getLineNumber());        
        super.startElement(uri, localName, qName, newAttrs);
    }
}

def text = '''
<root>
  <a>one!</a>
  <a>two!</a>
</root>'''

def root = new MySlurper().parseText(text)

root.a.each { println it.@_srmLineNum }

上面添加了行号属性。您也许可以尝试设置自己的错误处理程序,它可以从定位器中读取行号。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-06
    • 1970-01-01
    • 2023-03-29
    • 2020-04-29
    • 1970-01-01
    • 2021-09-06
    相关资源
    最近更新 更多