2015-09-06 68 views
2

好吧,在任何人问我为什么我使用DOM解析器而不是SAX的XML文件之前,原因很简单。我觉得DOM更容易使用,而不是SAX,因为我的XML文件通常非常小,所以它不需要太多内存就可以通过SAX解析它,而不是SAX是基于事件的XML解析器,它解析XML文件一步一步适合大型XML文件。使用DOM解析器将XML文件输出到文本文件?

所以现在我有这个示例XML文件在这里:

<?xml version="1.0"?> 
<schedule id="backup" duration="86400"> 
<datapoint time="0" speed="1" speednoise=".5" concurrency="8" concurrencynoise="1" interval="300" intervalnoise="300"/> <!-- 12am --> 
<datapoint time="7200" speed="1" speednoise=".5" concurrency="8" concurrencynoise="1" interval="300" intervalnoise="300"/> <!-- 2am --> 
<datapoint time="7201" speed="1" speednoise=".5" concurrency="0" concurrencynoise="0" interval="300" intervalnoise="300"/> <!-- 2:00:01am --> 
<datapoint time="86399" speed="1" speednoise=".5" concurrency="0" concurrencynoise="0" interval="10" intervalnoise="0"/> <!-- 11:59:59pm --> 
</schedule> 

我的代码:

try { 
     //this is the text file that i want to write into 
     BufferedWriter writer = new BufferedWriter(new FileWriter("new_backup.txt")); 
     //this is the file that i want to read from 
     File fXmlFile = new File("backup.xml"); 

     DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); 
     DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); 
     Document doc = dBuilder.parse(fXmlFile); 
     doc.getDocumentElement().normalize(); 
     NodeList nList = doc.getElementsByTagName("datapoint"); 
     for (int i = 0; i < nList.getLength(); i++) { 
      Node node = nList.item(i); 
      if (node.getNodeType() == Node.ELEMENT_NODE) { 
       Element eElement = (Element) node; 
       System.out.println("Time : " + eElement.getAttribute("time")); 
       System.out.println("Speed : " + eElement.getAttribute("speed")); 
       System.out.println("SpeedNoise : " + eElement.getAttribute("speednoise")); 
       System.out.println("Concurrency : " + eElement.getAttribute("concurrency")); 
       System.out.println("ConcurrencyNiose : " + eElement.getAttribute("concurrencynoise")); 
       System.out.println("Interval : " + eElement.getAttribute("interval")); 
       System.out.println("IntervalNoise : " + eElement.getAttribute("intervalnoise")); 
       if (eElement.hasChildNodes()) { 
        NodeList nl = node.getChildNodes(); 
        for (int j = 0; j < nl.getLength(); j++) { 
         Node nd = nl.item(j); 
         String name = nd.getTextContent(); 
         if (name != null && !name.trim().equals("")) { 
          System.out.print(name.trim() + ","); 
          //System.out.print(" "); 
          writer.write(nd.getTextContent().trim() + " "); 
         } 

        } 
        System.out.println(""); 
        writer.write("\n"); 
       } 
      } 
     } 
     writer.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

@SuppressWarnings("unused") 
private static String getTagValue(String sTag, Element eElement) { 
    NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes(); 
    Node nValue = (Node) nlList.item(0); 
    return nValue.getNodeValue(); 
} 
} 

Output: An empty text file.

什么我错在这里做什么? DOM解析器是否应该在元素为“数据点”的XML文件的节点上工作?当我将输出打印到系统控制台时,它会将我的结果返回给我,但是当我将它放入文本文件时,它是空的。我是新来的这种解析器,我正在为一个项目在学校做这个。

Console Output: Time : 0 
Speed : 1 
SpeedNoise : .5 
Concurrency : 8 
ConcurrencyNiose : 1 
Interval : 300 
IntervalNoise : 300 
Time : 7200 
Speed : 1 
SpeedNoise : .5 
Concurrency : 8 
ConcurrencyNiose : 1 
Interval : 300 
IntervalNoise : 300 
Time : 7201 
Speed : 1 
SpeedNoise : .5 
Concurrency : 0 
ConcurrencyNiose : 0 
Interval : 300 
IntervalNoise : 300 
Time : 86399 
Speed : 1 
SpeedNoise : .5 
Concurrency : 0 
ConcurrencyNiose : 0 
Interval : 10 
IntervalNoise : 0 

但它并没有保存到我想要的文本文件中。

+1

解析器用于*阅读*。 –

+0

有什么方法可以使用另一个代码来将其输出保存到文本文件中? @ElliottFrisch – irlyh8coding

+0

尝试用'getNodeValue()'替换'getTextContent()'的所有用法。 “文本内容”通常是指元素的内容,而不是属性的值。 – VGR

回答

-2

请加writer.flush();右行,说writer.close();

close()方法调用一般的flush()以及但是我一直叫writer.flush();之前。 原因在于,在某些JDK实现中,作为关闭的一部分进行刷新时抛出的任何异常都被吞下。这里是相关的线程:difference between flush and close function in case of filewriter in java。向下滚动至@Jon Skeet回答

+0

从[close()方法的文档](https://docs.oracle.com/javase/8/docs/api/java/io/Writer.html#close - ):“关闭流,首先刷新它。”close()总是暗示flush()。 – VGR

+0

@VGR你会重新考虑更新后的评论吗? – chrisl08

+0

即使在JDK的实现中,Jon提到flush()是总是叫 – VGR

0

您的外部for循环正在迭代<datapoint>元素。这些元素没有任何子节点(<datapoint/>是一个空元素),因此从不输入if语句,这意味着什么也不会写入writer

您可能打算为您的数据点元素迭代属性。由于属性顺序可能是任意的,因此迭代不是最优的,所以您应该按照名称获取它们,就像在打印语句中一样。

+0

但即使我做了也不会改变任何东西,因为这个“datapoint”元素被用来从文件中获取属性并将其输出到控制台中。我理解对不起,如果我错了我还是比较新的Java。:( – irlyh8coding

+0

我的第二段是指*内*迭代,而不是外循环。 – Andreas