2011-05-18 161 views
1

我对JSoup有以下问题。JSoup:替换字符串添加新行

我想分析和修改下面的html代码:

<code> 
<style type="text/css" media="all"> 
@import url("http://hakkon-aetterni.at/modules/system/system.base.css?ll3lgd"); 
@import url("http://hakkon-aetterni.at/modules/system/system.menus.css?ll3lgd"); 
@import url("http://hakkon-aetterni.at/modules/system/system.messages.css?ll3lgd"); 
@import url("http://hakkon-aetterni.at/modules/system/system.theme.css?ll3lgd"); 

    </style> 
</code> 

我用下面的代码acheive说:

Elements cssImports= doc.select("style"); 
     for (Element src : cssImports) { 
      String regex ="url\\(\"(.)*\"\\)"; 
      String data =src.data(); 
      String link;   

      Pattern p = Pattern.compile(regex); 
      Matcher m = p.matcher(data); 

      while (m.find()){ 
       link=m.group().substring(5,m.group().length()-2); 
       doc=Jsoup.parse(doc.html().replace(link, "")); 
      } 
     } 

首先,它的工作原理。所有导入网址都替换为字符串“FOUND”。我遇到的问题是,我在最后一条导入语句和封闭的</style>标记之间找到了很多新行,这些标记之前没有。

任何线索为什么这是偶然的,我怎么能避免它?

对不起,格式不好,但我好像我的代码的一些部分刚刚发布时删除。围绕第一个代码块有一个样式标签...

+0

我实际上遇到了与jsoup完全相同的问题。我想这是jsoup试图通过插入额外的HTML来验证文档是'聪明'。我没有适合你的解决方案。我最终转而使用jericho HTML解析器。 – 2011-05-18 09:47:56

回答

2

那么,今天我登陆这个页面寻找做一个非常类似的事情,我相信我已经解决了它。希望有人在一个月后仍然在观看这个节目。 ;)

我发现工作得很好,而不是在每个循环中进行字符串替换和重新解析文档,以重建style元素的内容。 JSoup真正闪耀的地方之一就是API使编辑解析文档变得简单。

另一招,就是使用data()函数。 JSoup区分数据(例如scriptstyle)和html/text节点。主要区别在于应用于数据节点的HTML转义是而不是

把所有这些组合起来,这下面的代码段应该与您FOUND文本,但不改变文档的格式替换您导入的样式表参:

// compile the regex before entering the loop, as it's a relatively expensive operation 
Pattern pattern = Pattern.compile("url\\(\"(.)*\"\\)"); 
for(Element styleElem : doc.getElementsByTag("style")) { 

    String data = styleElem.data(); 
    StringBuffer newData = new StringBuffer(); 
    Matcher matcher = pattern.matcher(data); 

    while(matcher.find()) { 
     matcher.appendReplacement(newData, "FOUND"); 
    } 
    matcher.appendTail(newData); 

    styleElem.appendChild(new DataNode(newData.toString(), base.toExternalForm())); 
} 

附:我假设你已经变得漂亮了。由于您的文档解析代码未显示,因此请务必在解析后双倍地拨打document.outputSettings().prettyPrint(false);

P.P.S.在我自己的代码中,我使用了一个更宽容(稍微丑陋的)正则表达式来查找导入。它允许用户省略URL声明,引号,parens等等,因为野外的HTML往往会做所有这些事情。我在我的代码中声明如下:

public static final Pattern CSS_IMPORT_PATTERN = Pattern.compile("(@import\\s+(?:url)?\\s*\\(?\\s*['\"]?)(.*?)([\\s'\";,)]|$)"); 
+0

嗨,目前还不清楚“base.toExternalForm()”来自哪里。你可以显示代码中“基地”实例化的部分,所以很清楚这是什么类型的对象。谢谢! – jmort253 2011-07-18 22:53:27

+0

我弄明白了。虽然我的问题涉及在样式块中保留“文字”引号,但此解决方案有助于解决问题。 +1 – jmort253 2011-07-18 23:07:14