1

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>

私はそれを達成するために次のコードを使用しています:

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, ""));
            }
        }

まず、それは機能します。すべてのインポート URL は文字列 " " に置き換えられFOUNDます。私が抱えている問題は、最後の import ステートメントとクローズされた</style>Tag の間に新しい行がたくさんあることです。

なぜこれが起こっているのか、どうすれば回避できるのか手がかりはありますか?

フォーマットが悪くて申し訳ありませんが、コードの一部が投稿時に削除されているようです。最初のコードブロックを囲むスタイルタグがあります...

4

1 に答える 1

2

さて、私は今日このページに非常に似たようなことをしようとして着陸しました、そして私はそれを解決したと信じています。うまくいけば、1か月後の今でも、誰かがこれを監視していると思います。;)

私がうまく機能していることがわかったのは、文字列の置換を行ってループごとにドキュメントを再解析する代わりに、style要素のコンテンツを再構築することでした。JSoupが本当に優れている点の1つは、APIが解析されたドキュメントの編集をいかに簡単にするかということです。

もう1つのトリックは、data()関数を使用することです。JSoupは、データ(scriptおよびstyle)ノードと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()));
}

PS私はあなたがかなり印刷をオフにしたと思います。ただし、ドキュメントの解析コードは表示されないため、解析後に必ず呼び出してdocument.outputSettings().prettyPrint(false);ください。

PPS私自身のコードでは、インポートを見つけるために、より寛容な(そして少し醜い)正規表現を使用しています。これにより、ユーザーはURL宣言、引用符、親子などを省略できます。これは、実際のHTMLではこれらすべてのことを実行する傾向があるためです。私はそれを私のコードで次のように宣言しています:

public static final Pattern CSS_IMPORT_PATTERN = Pattern.compile("(@import\\s+(?:url)?\\s*\\(?\\s*['\"]?)(.*?)([\\s'\";,)]|$)");
于 2011-06-23T21:10:10.040 に答える