使用JOOX的remove()方法删除XML节点后如何移除遗留的空行
使用JOOX的remove()方法删除XML节点后如何移除遗留的空行
嘿,我完全懂你这种烦恼——删除XML节点后留下的空行看着特别别扭,明明节点已经没了,却还留着一大块空白。咱们来搞定这个问题!
首先得搞清楚为啥会出现这个空行:你用template.find("Tag1").remove()只是删掉了<Tag1>节点本身,但原来节点所在行的缩进、换行这些空白内容,其实是以文本节点的形式留在XML文档里的。你之前尝试的xpath//text()[normalize-space(.) = '']没生效,大概率是因为范围太广,或者没精准定位到Data节点下的那些空白文本。
给你几个实用的解决方案,你可以根据自己的场景选:
方案一:精准清理目标节点下的空白文本节点
既然空行出现在<Data>节点内部,那咱们就只清理这个节点下的空白文本,不会影响文档其他地方的合法空白。修改你的代码如下:
final Match template = $(IOUtils.toString(Objects.requireNonNull( MyClass.class.getClassLoader().getResourceAsStream("templates/test.xml")), StandardCharsets.UTF_8)); if (someCriteria()) { // 先删除目标节点 template.find("Tag1").remove(); // 清理Data节点下所有仅含空白的文本节点 template.find("Data").xpath("text()[normalize-space(.) = '']").remove(); }
这个xpath会精准匹配<Data>里那些只包含空格、换行、制表符的文本节点,把它们删掉后,空行就消失了。
方案二:只删除目标节点相邻的空白
如果你不想清理<Data>下所有空白,只想删掉Tag1留下的那行空白,可以直接针对Tag1的相邻节点操作:
final Match template = $(IOUtils.toString(Objects.requireNonNull( MyClass.class.getClassLoader().getResourceAsStream("templates/test.xml")), StandardCharsets.UTF_8)); if (someCriteria()) { Match tag1 = template.find("Tag1"); // 先检查并删除Tag1前面的空白文本节点 Node prevSibling = tag1.get(0).getPreviousSibling(); if (prevSibling != null && prevSibling.getNodeType() == Node.TEXT_NODE && prevSibling.getTextContent().trim().isEmpty()) { $(prevSibling).remove(); } // 删除Tag1节点本身 tag1.remove(); }
这种方式更精准,只会处理和Tag1紧挨着的空白,不会误删其他必要的空白格式。
方案三:加载XML时忽略空白(需注意局限性)
如果你的XML文档不需要保留任何无关空白,也可以在加载文档时就配置忽略元素内容里的空白。不过这个方法需要XML有对应的DTD或Schema,否则解析器没法判断哪些空白是无关的,代码如下:
// 构建忽略空白的文档解析器 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setIgnoringElementContentWhitespace(true); // 加载XML内容 String xmlContent = IOUtils.toString(Objects.requireNonNull( MyClass.class.getClassLoader().getResourceAsStream("templates/test.xml")), StandardCharsets.UTF_8); Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(xmlContent))); // 初始化JOOX的Match对象 Match template = $(doc); if (someCriteria()) { template.find("Tag1").remove(); }
这个方法适合你的XML有明确结构定义的场景,不然可能达不到预期效果。
试试上面的方法,应该就能彻底去掉那些讨厌的空行啦!
备注:内容来源于stack exchange,提问作者Martin WasGehtSieDasAn
相关产品推荐
相关产品推荐

