根据您的问题和 cmets,您似乎只想修改所选元素的直接文本节点而不修改所选文本的潜在内部元素的文本节点,因此在
的情况下
<div>a b <span>b c</span></div>
如果我们要修改b,我们只修改直接放在<div>中的一个,而不是在<span>中的一个。
<div>a b <span>b c</span></div>
^ ^----don't modify because it is in <span>, not *directly* in <div>
|
modify
文本不像<div> <span>等那样被视为ElementNode,但在DOM中它被表示为TextNode,所以如果我们有像<div> a <span>b</span> c </div>这样的结构,那么它的DOM表示将是
Element: <div>
├ Text: " a "
├ Element: <span>
│ └ Text: "b"
└ Text: " c "
如果我们想包装部分文本到<span>(或任何其他标签)中,我们实际上是在拆分单个TextNode
├ Text: "foo bar baz"
成系列:
├ Text: "foo "
├ Element: <span>
│ └ Text: "bar"
└ Text: " baz"
要创建使用该想法的解决方案TextNode API 为我们提供了非常有限的工具集,但在可用的方法中我们可以使用
-
splitText(index) 修改原始 TextNode 将拆分的“左侧”保留在其中并返回新的 TextNode 保留拆分的剩余(右侧),就像 TextNode node1 持有 "foo bar" 之后 TextNode node2 = node1.splitText(3); node1 将持有 @ 987654343@ 而node2 将保持" bar" 并将被放置为node1 之后的直接兄弟
-
wrap(htmlElement)(继承自 Node 超类)将 TextNode 包装在表示 htmlElement 的 ElementNode 中,例如 node.wrap("<span class='myClass'>") 将导致 <span class='myClass>text from node</span>。
通过上面的“工具”,我们可以创建类似的方法
static void wrapTextWithElement(TextNode textNode, String strToWrap, String wrapperHTML) {
while (textNode.text().contains(strToWrap)) {
// separates part before strToWrap
// and returns node starting with text we want
TextNode rightNodeFromSplit = textNode.splitText(textNode.text().indexOf(strToWrap));
// if there is more text after searched string we need to
// separate it and handle in next iteration
if (rightNodeFromSplit.text().length() > strToWrap.length()) {
textNode = rightNodeFromSplit.splitText(strToWrap.length());
// after separating remining part rightNodeFromSplit holds
// only part which we ware looking for so lets wrap it
rightNodeFromSplit.wrap(wrapperHTML);
} else { // here we know that node is holding only text to wrap
rightNodeFromSplit.wrap(wrapperHTML);
return;// since textNode didn't change but we already handled everything
}
}
}
我们可以这样使用:
Document doc = Jsoup.parse("<div>b a b <span>b c</span> d b</div> ");
System.out.println("BEFORE CHANGES:");
System.out.println(doc);
Element id1 = doc.select("div").first();
for (TextNode textNode : id1.textNodes()) {
wrapTextWithElement(textNode, "b", "<span class='x'>");
}
System.out.println();
System.out.println("AFTER CHANGES");
System.out.println(doc);
结果:
BEFORE CHANGES:
<html>
<head></head>
<body>
<div>
b a b
<span>b c</span> d b
</div>
</body>
</html>
AFTER CHANGES
<html>
<head></head>
<body>
<div>
<span class="x">b</span> a
<span class="x">b</span>
<span>b c</span> d
<span class="x">b</span>
</div>
</body>
</html>