JAVA - 如何读取XML文件并将每个节点保存到字符串数组

时间:2017-11-21 14:27:42

标签: java arrays xml jdom

我是java和XML的新手。 我的目标是从我的XML文件中获取信息并将其保存到字符串数组中,以便稍后在我的代码中用于测试我的网站。 XML包含每个页面的元素,分为3类:名称,属性,文本。 我的第一步是隔离我想要的数据并将其打印出来,并且已经卡住了。

以下是我的XML文件的示例(原始文件中有更多节点使用相同的结构):

<?xml version="1.0" encoding=""ISO-8859-1""?>
<config>
  <HomeScreenName>
    <Logo>Logo</Logo>
    <Mainimage>Main image</Mainimage>
    <Maintext>Main text</Maintext>
    <Backupbutton>Backup button</Backupbutton>
    <ViewBackupbutton>View Backup button</ViewBackupbutton>
    <Version>Version</Version>
    <Cancelaccountbutton>Cancel account button</Cancelaccountbutton>
  </HomeScreenName>
  <HomeScreenAttributes>
    <Logo>/html/body/div[1]/div[1]</Logo>
    <Mainimage>//*[@id="img-content"]</Mainimage>
    <Maintext>/html/body/div[1]/div[3]/h3</Maintext>
    <Backupbutton>/html/body/div[1]/div[3]/div[1]/a/span</Backupbutton>
    <ViewBackupbutton>/html/body/div[1]/div[3]/div[2]/a/span</ViewBackupbutton>
    <Version>//*[@id="version"]</Version>
    <Cancelaccountbutton>//*[@id="unregister"]/p</Cancelaccountbutton>
  </HomeScreenAttributes>
  <HomeScreenText>
    <Logo />
    <Mainimage />
    <Maintext>Secure backup</Maintext>
    <Backupbutton>Back Up</Backupbutton>
    <ViewBackupbutton>View Your Backups</ViewBackupbutton>
    <Version>Version 1.0.3</Version>
    <Cancelaccountbutton />
  </HomeScreenText>
 </config>

从这个XML我想创建4个数组: 首先只有每个节点的名称: array1 = [HomeScreenName,HomeScreenAttributes,HomeScreenText]

然后我想要一个每个节点属性的数组: 像这样的东西:array2(来自HomeScreenName)= [徽标,主图像,主文本,备份按钮,查看备份按钮,版本,取消帐户按钮]

我有两个主要问题:

  1. 如何获取我想要的数据,而不是XML中的所有数据。

  2. 如何保存数据(我想要数组,但我愿意接受建议)。

  3. 以下是我打印XML文件中每个节点的代码:

    import java.io.File;
    import java.io.IOException;
    import java.util.List;
    import org.jdom.Document;
    import org.jdom.Element;
    import org.jdom.JDOMException;
    import org.jdom.input.SAXBuilder;
    
    public class readConfigXML{
    public static void main(String[] args) 
    {
    
      SAXBuilder builder = new SAXBuilder();
      String folderPath = "C:\\Users\\udi\\Documents\\external\\XML\\";
      String fileName = "configTest.xml";
      String filePath = folderPath + fileName;  
      File xmlFile = new File(filePath);
    
      try {
            Document document = (Document) builder.build(xmlFile);
            Element rootNode = document.getRootElement();
            List configList = rootNode.getChildren();
            for (int i = 0; i < configList.size(); i++) 
            {
                Element node = (Element) configList.get(i);
                List dataNodes = node.getChildren();
                for (int j = 0; j < dataNodes.size(); ++j) 
                {
                    Element dataNode = (Element) dataNodes.get(j);
                    System.out.println(dataNode.getName());
                }
            }       
        }
      catch (IOException io) 
      {
        System.out.println(io.getMessage());
      } 
      catch (JDOMException jdomex) 
      {
        System.out.println(jdomex.getMessage());
      }
    }
    }
    

    任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:1)

这是一个简单的代码,可以实现你想要的。我在这段代码中使用了Lists。为了获得您想要的数据,除了从xml文件中读取之外,我没有任何其他方法来检查节点。

 import java.io.File;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    import org.jdom.Document;
    import org.jdom.Element;
    import org.jdom.JDOMException;
    import org.jdom.input.SAXBuilder;



    public class readConfigXML {

 // the nodes that we want to be read
        public static List<String>  wantedNodes  = new ArrayList<String>() ;
// the attributes that we want to be read
        public static List<String>  wantedAttributes= new ArrayList<String>()   ;
        // init the nodes and attributes wanted here
        public static void init(){
            wantedNodes.add("HomeScreenName") ;
            wantedNodes.add("HomeScreenAttributes") ;
            wantedAttributes.add("Logo") ; // ...
        }

        public static void main(String[] args) 
        {
            // here init your wanted nodes and attributes
            init() ;

          SAXBuilder builder = new SAXBuilder();
          String folderPath = "C:\\Users\\udi\\Documents\\external\\XML\\";
          String fileName = "configTest.xml";
          String filePath = folderPath + fileName;  
          File xmlFile = new File(filePath);

          List<String> nodes = new ArrayList<String>() ;
          List<String> attributeNodes = new ArrayList<String>() ;

          try {
                Document document = (Document) builder.build(xmlFile);
                Element rootNode = document.getRootElement();
                List configList = rootNode.getChildren();
                for (int i = 0; i < configList.size(); i++) 
                {
                    Element node = (Element) configList.get(i);
                    // check if this node is wanted  
                    if(wantedNodes.contains(node.getName())){
                        nodes.add(node.getName()) ;
                        List dataNodes = node.getChildren();
                        for (int j = 0; j < dataNodes.size(); ++j) 
                        {
                            Element dataNode = (Element) dataNodes.get(j);
                            // check if this attribute is wanted 
                            if(wantedAttributes.contains(dataNode.getName())){
                                attributeNodes.add(dataNode.getValue()) ;
                            }
                        }
                    }
                }  

            }
          catch (IOException io) 
          {
            System.out.println(io.getMessage());
          } 
          catch (JDOMException jdomex) 
          {
            System.out.println(jdomex.getMessage());
          }
        }

    }

答案 1 :(得分:0)

标准JDK包org.w3c.dom(我没有检查,但您的org.jdom可能必须具有相同或相似:

  
      
  1. 如何获取我想要的数据,而不是XML中的所有数据。
  2.   

每个节点都有一个节点类型。然后它可能有一个TEXT_NODE类型的子项。 (节点类型为shortNode接口具有类型常量。例如

if (dataNode.getNodeType() == Node.TEXT_NODE)

因此,当您遍历节点子节点时 - 检查它是否是TEXT_NODE,那么它就是您需要的数据。  例如元素(节点)<Logo>Logo</Logo>有一个子文本节点,其值为&#34; Logo&#34;你可以买它来叫node.getTextContent()

BTW:小心getTextContent()如果它是混合节点(带有文本和其他子元素),它将返回所有孩子的文本。我在你的例子中没有看到它,但首先检查节点类型,如果是文本节点,你可以使用它。

  
      
  1. 如何保存数据(我想要数组,但我可以接受建议)。
  2.   

由您决定,但只要Java没有动态数组,最好使用List作为示例LinkedListArrayList来捕获来自未知数量元素的数据

如果你仍然希望拥有数组,那么在通过调用List方法从结果toArray()完成get数组之后。

此外,对于一般用途(如果XML树具有未知或大量级别,则需要使用递归来处理子节点)。如果不是这种情况并且您确切知道XML的深度,那么可以使用嵌套的for循环,但仍然需要递归。

答案 2 :(得分:0)

所以我能找到的最好的方法是编辑我的XML,以便所有主子节点都具有相同的名称,具有不同的属性,如下所示:

<Page id="Home">
<Page id="Sign in">

获取所有主要节点名称的代码是:

public static void main(String[] args) 
{
    String folderPath = "C:\\XML\\";
    String fileName = "2.xml";
    String xmlFile = folderPath + fileName;         
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder dBuilder;
    try
    /// gets the main nodes in the config and saves them to a list
    {
        dBuilder = dbFactory.newDocumentBuilder();
        Document doc = dBuilder.parse(xmlFile);
        doc.getDocumentElement().normalize();
        //System.out.println("Root element is:" + doc.getDocumentElement().getNodeName());
        NodeList mainList = doc.getElementsByTagName("Page");
        List<String> list = new ArrayList<String>();
        for (int temp = 0; temp < mainList.getLength(); temp++)
        {
            Node mainNode = mainList.item(temp);
            Element eElement = (Element) mainNode;
            list.add(eElement.getAttribute("id"));
            System.out.println( list.get(temp));
        }
        System.out.println(list);
        System.out.println("----------------------------------------");

    }
    catch(SAXException | ParserConfigurationException | IOException e1)
    {
        e1.printStackTrace();
    }

}

输出将是:

主页 登入 寄存器 登录 并作为列表:[主页,登录,注册,登录]