Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 仅在文本部分用jsoup替换字符串_Java_Jsoup - Fatal编程技术网

Java 仅在文本部分用jsoup替换字符串

Java 仅在文本部分用jsoup替换字符串,java,jsoup,Java,Jsoup,我发现了几个问题和答案相似的主题,但我仍在努力解决这个问题: 我想用Jsoup解析一些html,这样我可以替换,例如 "changeme" 与 changeme ,但仅当它出现在html的文本部分时,如果它是标记的一部分,则为否。因此,从这个html开始: <body> <p><a href="http://changeme.html">test changeme app</a></p> </BODY> </HTM

我发现了几个问题和答案相似的主题,但我仍在努力解决这个问题:

我想用Jsoup解析一些html,这样我可以替换,例如

"changeme"

changeme
,但仅当它出现在html的文本部分时,如果它是标记的一部分,则为否。因此,从这个html开始:

<body>
<p><a href="http://changeme.html">test changeme app</a></p>
</BODY>
</HTML>

我想说的是:

<body>
<p><a href="http://changeme.html">test <changed>changeme</changed> app</a></p>
</BODY>
</HTML>

我尝试了几种方法,这一种更接近预期结果:

Document doc = null;
try {
    doc = Jsoup.parse(new File("tmp1450348256397.txt"), "UTF-8");
} catch (Exception ex) {
}

Elements els = doc.body().getAllElements();
for (Element e : els) {
    if (e.text().contains("changeme")) {
        e.html(e.html().replaceAll("changeme","<changed>changeme</changed>"));
    }
}
html = doc.toString();
System.out.println(html);
单据单据=null;
试一试{
doc=Jsoup.parse(新文件(“tmp1450348256397.txt”),“UTF-8”);
}捕获(例外情况除外){
}
元素els=doc.body().getAllegements();
对于(元素e:els){
如果(例如,text()包含(“changeme”)){
e、 html(例如html().replaceAll(“changeme”、“changeme”);
}
}
html=doc.toString();
System.out.println(html);
但通过这种方法,我发现了两个问题:

<body>
<p><a href="http://<changed>changeme</changed> .html">test
    <changed>
        changeme
    </changed> 
app</a></p>
</BODY>
</HTML>

  • 换行符在我介绍的新元素之前和之后插入。这不是一个真正的问题,因为如果我使用#changed#进行替换,并且在doc.toString()之后,我可以将它们再次替换为所需的值(使用<>)

  • 真正的问题:href中的URL已被修改,我不希望发生这种情况


  • 想法?Thx.

    我认为您的问题在于您正在替换html元素,而不仅仅是它的文本,更改:

    e.html(e.html().replaceAll("changeme","<changed>changeme</changed>"));
    
    e.html(e.html();
    

    e.text(e.text().replaceAll(“changeme”、“changeme”);
    

    换行问题可能可以通过执行
    doc.outputSettings().prettyPrint(false)来解决执行之前
    html=doc.toString()

    最后,我使用TextNodes尝试了这个解决方案(在问题的末尾):

    这是生成的代码:

    Elements els = doc.body().getAllElements();
    for (Element e : els) {
        for (Node child : e.childNodes()){
            if (child instanceof TextNode && !((TextNode) child).isBlank()) {
                ((TextNode)child).text(((TextNode)child).text().replaceAll("changeme","<changed>changeme</changed>"));
            }
        }
    }   
    
    Elements els=doc.body().getAllegements();
    对于(元素e:els){
    对于(节点子节点:e.childNodes()){
    if(TextNode&!((TextNode)child.isBlank()的子实例){
    ((TextNode)child.text(((TextNode)child.text().replaceAll(“changeme”,“changeme”));
    }
    }
    }   
    
    现在输出是预期的,它甚至没有引入额外的中断线。在这种情况下,prettyPrint必须设置为True

    唯一的问题是,我并不真正理解使用
    TextNode
    vs
    Element.text()
    的区别。如果有人想提供一些信息,我们将不胜感激

    谢谢。

    这是我的解决方案:

    String html=""
        +"<p><a href=\"http://changeme.html\">"
        +   "test changeme "
        +   "<div class=\"changeme\">"
        +     "inner text changeme"
        +   "</div>"
        +   " app</a>"
        +"</p>";
    Document doc = Jsoup.parse(html);
    Elements els = doc.body().getAllElements();
    for (Element e : els) {
        List<TextNode> tnList = e.textNodes();
        for (TextNode tn : tnList){
            String orig = tn.text();
            tn.text(orig.replaceAll("changeme","<changed>changeme</changed>")); 
        }
    }
    
    html = doc.toString();
    System.out.println(html);
    
    String html=“”
    +“”
    +“

    ”; Document doc=Jsoup.parse(html); 元素els=doc.body().getAllegements(); 对于(元素e:els){ List tnList=e.textNodes(); 对于(TextNode tn:tnList){ 字符串orig=tn.text(); tn.text(原始替换名称(“更改名称”、“更改名称”)); } } html=doc.toString(); System.out.println(html);
    TextNodes始终是叶节点,即它们不包含更多HTML元素。在最初的方法中,您使用替换的
    changme
    字符串替换元素的HTML。您只检查changeme是否是TextNodes内容的一部分,但替换元素HTML字符串中的每个引用,包括TextNodes之外的所有引用

    我的解决方案基本上与您的类似,但我使用JSoup方法
    textNodes()
    。这样我就不需要打字了

    附言。
    当然,我的解决方案以及您的解决方案最终将包含
    changedchangeme/changed
    ,而不是
    changeme
    。这可能不是你想要的。如果您不想这样做,那么您的结果将不再是有效的HTML,因为
    changed
    不是有效的HTML标记。在这种情况下,Jsoup不会帮助您。但是,您当然可以在结果字符串中再次替换所有
    changedchangeme/changed
    ——在JSoup之外。

    这是我尝试的第一件事,但它不起作用,所有html标记都丢失了。输出将是:
    testchangeme
    。但是,。。。你走了。不过,预印(假)效果很好,谢谢。这有点奇怪,因为这是一个来自Python的lxml的端口,并且prettyPrint设置为true。好的,感谢您对TextNodes的补充解释。
    Elements els = doc.body().getAllElements();
    for (Element e : els) {
        for (Node child : e.childNodes()){
            if (child instanceof TextNode && !((TextNode) child).isBlank()) {
                ((TextNode)child).text(((TextNode)child).text().replaceAll("changeme","<changed>changeme</changed>"));
            }
        }
    }   
    
    String html=""
        +"<p><a href=\"http://changeme.html\">"
        +   "test changeme "
        +   "<div class=\"changeme\">"
        +     "inner text changeme"
        +   "</div>"
        +   " app</a>"
        +"</p>";
    Document doc = Jsoup.parse(html);
    Elements els = doc.body().getAllElements();
    for (Element e : els) {
        List<TextNode> tnList = e.textNodes();
        for (TextNode tn : tnList){
            String orig = tn.text();
            tn.text(orig.replaceAll("changeme","<changed>changeme</changed>")); 
        }
    }
    
    html = doc.toString();
    System.out.println(html);