【问题标题】:jsoup remove outer html tag - code HTML elementjsoup 删除外部 html 标记 - 代码 HTML 元素
【发布时间】:2020-05-30 14:56:31
【问题描述】:

这看起来很简单,但显然我做错了什么。这是我的 HTML - 我正在尝试在 pre 标签下创建单数代码标签和嵌套代码标签 - 生成的内容将是“带有代码的单行框”以及带有 pre 标签“带有代码的大框”。还有一些我无法使用标准方法摆脱的空段落标签 - 在测试段落中没有文本后删除元素。这是输入

        <h1>Module Description and Learning Objectives</h1>  
        <p> 
        </p> 
        <pre>                
        <p>
        <code>2020-02-13 12:49:15 DEBUG StackTraceElement:48 -</code>
        </p>
        <p>
        <code>2020-02-13 12:49:15 DEBUG StackTraceElement:48 - sects.title</code>
        </p>
        <p>
        <code>2020-02-13 12:49:15 DEBUG StackTraceElement:48 - sects.id=1</code>
        </p>
        <p>
        </p>
        </pre> 
        <p>Sentence 1</p> 
        <p> 
        <code>System.out.println("id:"+element.attr("id"));</code> 
        </p> 
        <p>Sentence 2</p> 
        <p> 
        <code>System.out.println("src:"+element.attr("src"));</code> 
        </p> 
        <p>Sentence 3</p> 
        <p> 
        <code>System.out.println("alt:"+element.attr("alt"));</code> 
        </p> 
        <p> 
        </p> 

这是我的代码(不要像结构一样遵循名称,中间代码名称:)

          Elements pWithCodeTagList = docXMLformat.select("code");
          if (pWithCodeTagList.size() > 0) {
              for (Element pTag : pWithCodeTagList) {
                   System.out.println("pTag=" + pTag.text() + " " + pTag.tagName());
                   pTag.unwrap();
              }
          }

这是 eclipse 中的输出 - 我确实在选择代码标签并期望父 p 消失

 pTag=2020-02-13 12:49:15 DEBUG StackTraceElement:48 - code
 pTag=2020-02-13 12:49:15 DEBUG StackTraceElement:48 - sects.title code
 pTag=2020-02-13 12:49:15 DEBUG StackTraceElement:48 - sects.id=1 code
 pTag=System.out.println("id:"+element.attr("id")); code
 pTag=System.out.println("src:"+element.attr("src")); code
 pTag=System.out.println("alt:"+element.attr("alt")); code

这是结果:我希望段落标签消失,而不是代码标签!

   <h1>Module Description and Learning Objectives</h1> 
                <p> 
                </p> 
                <pre>                
                    <p>
                    2020-02-13 12:49:15 DEBUG StackTraceElement:48 -
                </p>
                    <p>
                    2020-02-13 12:49:15 DEBUG StackTraceElement:48 - sects.title
                </p>
                    <p>
                    2020-02-13 12:49:15 DEBUG StackTraceElement:48 - sects.id=1
                </p>
                    <p>
                    </p>
                </pre> 
                <p>Sentence 1</p> 
                <p> System.out.println("id:"+element.attr("id")); </p> 
                <p>Sentence 2</p> 
                <p> System.out.println("src:"+element.attr("src")); </p> 
                <p>Sentence 3</p> 
                <p> System.out.println("alt:"+element.attr("alt")); </p> 
                <p> 
                </p> 

我已经接触过文档的这个区域,在此之前我已经删除了代码标签周围的跨度标签,并且不得不从行内容中删除所有行控制字符,也许 PRE 和 CODE 不能像其他标签 - 我知道他们不应该这样做,但是......而且,我试图将标签和内容保持在同一行,这样我的“代码框”就尽可能地纤细了:

 <pre>                
 <code>2020-02-13 12:49:15 DEBUG StackTraceElement:48 -</code>
 <code>2020-02-13 12:49:15 DEBUG StackTraceElement:48 - sects.title</code>
 <code>2020-02-13 12:49:15 DEBUG StackTraceElement:48 - sects.id=1</code>
  </pre> 
  <p>Sentence 1</p> 
  <code>System.out.println("id:"+element.attr("id"));</code> 
  <p>Sentence 2</p> 
  <code>System.out.println("src:"+element.attr("src"));</code> 
  <p>Sentence 3</p> 
  <code>System.out.println("alt:"+element.attr("alt"));</code> 

【问题讨论】:

  • 来自文档:“unwrap​() - 从 DOM 中删除匹配的元素,并将它们的子元素移到它们的父元素中。”我会说这是预期的行为,不是吗?只需尝试选择要删除的元素(p)。
  • 嗨 - 是的 - 你的分析绝对正确,我在想“礼物被打开,选择礼物并打开(移除)纸张(外层),但它似乎是”选择包装纸并将其移除” - 下面的答案增加了更多,所以我选择它作为答案,但也感谢你的正确。

标签: html jsoup pre


【解决方案1】:

您的选择器正在选择 code 元素,而不是 p 元素,这就是它们被删除的原因。您应该选择具有code 标记的p 元素和unwrap() 那些。 p:has(code)

此外,如果您想将它们全部解包,则不需要迭代它们并在每个上调用 unwrap(除非您想为每个它们执行额外的逻辑)。你可以拨打Elements#upwrap()

Elements pWithCodeTagList = docXMLformat.select("p:has(code)");
pWithCodeTagList.unwrap();

要找到空的p 标签,您可以使用:matches 选择器,它在文本上执行正则表达式,然后只查找空格或什么都没有:p:matches(^\s?$)

Elements emptyPs = docXMLformat.select("p:matches(^\\s?$)");
emptyPs.remove();

【讨论】:

  • 非常感谢 - 你的 4 行代码解决了我所有的问题!
猜你喜欢
  • 1970-01-01
  • 2013-06-06
  • 2020-03-24
  • 2015-08-09
  • 2011-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多