Bạn "không thể" tắt tính năng này. Bởi "không thể" tôi có nghĩa là không dễ dàng. Bạn sẽ phải đánh chặn/tái triển khai/ghi đè lên quá trình duyệt qua nút mà tôi nghĩ là quá nhiều. Bạn có thể làm điều này
String dom = Parser.unescapeEntities(doc.html(), false);
Cập nhật
Trước hết chúng ta phải xác định vị trí của vấn đề.
TextNode.java
void outerHtmlHead(StringBuilder accum, int depth,
Document.OutputSettings out) {
if ((out.prettyPrint())
&& ((((siblingIndex() == 0)
&& (this.parentNode instanceof Element)
&& (((Element) this.parentNode).tag().formatAsBlock()) && (!(isBlank()))) || ((out
.outline()) && (siblingNodes().size() > 0) && (!(isBlank())))))) {
indent(accum, depth, out);
}
boolean normaliseWhite = (out.prettyPrint())
&& (parent() instanceof Element)
&& (!(Element.preserveWhitespace(parent())));
Entities.escape(accum, getWholeText(), out, false, normaliseWhite,
false);
}
Đặc biệt vấn đề là ở đây
Entities.escape(accum, getWholeText(), out, false, normaliseWhite,false);
Entities.java
static void escape(StringBuilder accum, String string,
Document.OutputSettings out, boolean inAttribute,
boolean normaliseWhite, boolean stripLeadingWhite) {
boolean lastWasWhite = false;
boolean reachedNonWhite = false;
EscapeMode escapeMode = out.escapeMode();
CharsetEncoder encoder = out.encoder();
CoreCharset coreCharset = CoreCharset.access$300(encoder.charset()
.name());
Map map = escapeMode.getMap();
int length = string.length();
int codePoint;
for (int offset = 0; offset < length; offset += Character
.charCount(codePoint)) {
codePoint = string.codePointAt(offset);
if (normaliseWhite) {
if (StringUtil.isWhitespace(codePoint)) {
if ((stripLeadingWhite) && (!(reachedNonWhite)))
continue;
if (lastWasWhite)
continue;
accum.append(' ');
lastWasWhite = true;
continue;
}
lastWasWhite = false;
reachedNonWhite = true;
}
if (codePoint < 65536) {
char c = (char) codePoint;
switch (c) {
case '&':
accum.append("&");
break;
case ' ':
if (escapeMode != EscapeMode.xhtml)
accum.append(" ");
else
accum.append(" ");
break;
case '<':
if ((!(inAttribute)) || (escapeMode == EscapeMode.xhtml))
accum.append("<");
else
accum.append(c);
break;
case '>':
if (!(inAttribute))
accum.append(">");
else
accum.append(c);
break;
case '"':
if (inAttribute)
accum.append(""");
else
accum.append(c);
break;
default:
if (canEncode(coreCharset, c, encoder))
accum.append(c);
else if (map.containsKey(Character.valueOf(c)))
accum.append('&')
.append((String) map.get(Character.valueOf(c)))
.append(';');
else
accum.append("&#x")
.append(Integer.toHexString(codePoint))
.append(';');
}
} else {
String c = new String(Character.toChars(codePoint));
if (encoder.canEncode(c))
accum.append(c);
else
accum.append("&#x").append(Integer.toHexString(codePoint))
.append(';');
}
}
}
Ok bây giờ chúng tôi đã xác định được vấn đề, thì sao giải pháp. Đây là vấn đề. Thông thường bạn sẽ làm gì sẽ được ghi đè outerHtmlHead
(được gọi là cho mỗi nút khi gọi html()
hoặc toString()-calls outerHtml
hoặc outerHtml()
. Vấn đề là phương pháp này là package private vì vậy nó không thể nhìn thấy để ghi đè lên nó bên ngoài của gói.
Một cách dễ dàng sẽ được tải về mã nguồn của Jsoup và bao gồm lớp tùy chỉnh của bạn bên trong cùng một gói. Một sẽ phải thay đổi chế độ hiển thị của hai để được bảo vệ.
abstract void outerHtmlHead(StringBuilder paramStringBuilder, int paramInt, Document.OutputSettings paramOutputSettings);
abstract void outerHtmlTail(StringBuilder paramStringBuilder, int paramInt,Document.OutputSettings paramOutputSettings);
dự án sẽ có lỗi biên dịch trong mỗi lớp mở rộng class Node
về việc không thể giảm e khả năng hiển thị của một phương pháp ghi đè. Thay đổi chế độ hiển thị thành protected
. Sau đó bạn có thể triển khai một lớp mới mở rộng lớp TextNode
.Một cái gì đó như thế này cũng đủ tôi tin
public class RawTextNode extends TextNode {
@Override
protected void outerHtmlHead(StringBuilder accum, int depth, OutputSettings out) {
if ((out.prettyPrint())
&& ((((siblingIndex() == 0)
&& (parentNode() instanceof Element)
&& (((Element) parentNode()).tag().formatAsBlock()) && (!(isBlank()))) || ((out
.outline()) && (siblingNodes().size() > 0) && (!(isBlank())))))) {
indent(accum, depth, out);
}
}
}
và mã của bạn phải thay đổi cho phù
head.appendElement("script").attr("type", "application/javascript").appendChild(new RawTextNode(myJS, ""));
Nếu bạn để nó như nó là, văn bản sẽ được đại diện bởi TextNode
, bạn cần phải nói rõ nội dung phải được đại diện bởi lớp tùy chỉnh của bạn.
Tất nhiên bạn có thể đi sâu hơn và tạo một lớp mới xử lý theo cách chung chung các bộ phận script
.
Tôi đã cập nhật câu trả lời của tôi. – alkis