java - 使用 Java 删除 XML 文档上的重复节点标记

标签 java xml algorithm xml-parsing

我有以下 xml 文档:

<?xml version="1.0" ?>
<tag>text<b><b>bold</b> bold again</b><b><br/>the end </tag>

我需要删除重复的标签但保留其内容,所以结果是:

<?xml version="1.0" ?>
    <tag>text<b>bold bold again</b>the end </tag> 

我有以下代码:

import java.io.*;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.w3c.dom.Document;
import org.w3c.dom.*;
import java.util.Arrays;

import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;


import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;


public class TakeDuplicatesXml{

    public static void main(String[] args){

        try{
            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
            Document doc = docBuilder.parse("/Users/youruser/code/Exercises/file.xml");

            //get node list
            List<String> aux = new ArrayList<String>();
            removeDuplicate(doc.getDocumentElement(), aux);

            //print the new document out
            printXmlDocument(doc);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static void printXmlDocument(Document doc){
        try{
            DOMSource domSource = new DOMSource(doc);
            StringWriter writer = new StringWriter();
            StreamResult result = new StreamResult(writer);
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer transformer = tf.newTransformer();
            transformer.transform(domSource, result);
            System.out.println("XML IN String format is: \n" + writer.toString());
        }catch (Exception ex) {
            ex.printStackTrace();
        }

    }
  //with recursion
    public static void removeDuplicate(Node node, List<String>  aux){

        System.out.println(node.getNodeName());
        //check if that node exists already
        if(aux.contains(node.getNodeName())){
            node.getParentNode().removeChild(node);
        }else{
            //add node name to aux list
            aux.add(node.getNodeName());
        }

        NodeList nodeList = node.getChildNodes();

        for (int i = 0; i < nodeList.getLength(); i++) {
            Node currentNode = nodeList.item(i);
            if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
                //calls this method for all the children which is Element
                removeDuplicate(currentNode, aux);
            }
        }
    }
}

但结果不是我想要的,因为正在获取节点及其内容(粗体字消失了):

<tag>text<b> bold again</b><br/>the end </tag>

我该如何解决?我怎样才能让它更高效?

最佳答案

此类问题最好使用简单的 XSLT 转换来解决。您需要一个包含两个规则的样式表:一个复制所有内容不变的身份规则

<xsl:template match="*">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates select="child::node()"/>
  </xsl:copy>
</xsl:template>

还有另一个(更高优先级)删除嵌套 b 标签的规则:

<xsl:template match="b/b">
  <xsl:apply-templates/>
</xsl:template>

将这些包装在通常的样板中:

<xsl:stylesheet version="1.0" xmlns:xsl="http:www.w3.org/1999/XSL/Transform">

.. template rules go here ...

</xsl:stylesheet>

然后使用以下方法从您的 Java 程序中调用它:

公共(public)类 TakeDuplicatesXml{

public static void main(String[] args){

    try{
        TransformerFactory tFactory = TransformerFactory.newInstance();
        Templates t = tFactory.newTemplates(new File(... stylesheet file ....));
        Source doc = new StreamSource(
          new File("/Users/youruser/code/Exercises/file.xml"));
        t.newTransformer().transform(doc, new StreamResult(System.out));
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

关于java - 使用 Java 删除 XML 文档上的重复节点标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26330692/

相关文章:

java - Android - MediaPlayer + PowerManager.PARTIAL_WAKE_LOCK

java - 如何从 Eclipse 运行 Scuba 项目

xml - 使用shell脚本从xml标签获取属性值并转换为csv

algorithm - 未知算法名称

java - 有没有一种简单的方法可以在 Java 中创建可以在运行时修改并保存到文件的分层数据结构? (安卓工作室)

java - 在浮点处绘制图像 - Java

c# - 使用 Linq 读取 XML 并检查元素是否存在

c# - 在 XML 文档中查找重复的子节点

c# - 如何使用 C# 中的 struct 提供显示为 info 的数据?

Python:根据两个特征的唯一组合和第三个特征的条件删除重复项