2015-05-30 4 views
1

Я создаю игровой менеджер парового клона на Java, и у меня возникают проблемы с одной заключительной частью проекта. В левой части графического интерфейса я автоматически заполнял «плейлисты» игр, которые анализируются из XML-файла библиотеки, и я хотел бы получить игры только из этого плейлиста, когда нажимает на ListSelectionListener. В настоящее время я могу заполнять ВСЕ игры, хранящиеся в библиотеке, используя getElementsByTagName («Игра»), но мне нужно, чтобы они были конкретными для списка воспроизведения, которому также присваивается уникальный идентификатор с атрибутом attribute, установленным в true для «Id».XML-анализ - получение узлов только от родителя с определенным идентификатором

Однако в приведенном ниже коде мне нужно сделать что-то вроде readLib.getElementById (id) .getChildNodes(); но каждый раз, когда я делаю это, я получаю исключение nullpointer в этой строке. Есть идеи? Я чувствую, что я очень близко.

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); String [] gameArray = null;

try { 
     DocumentBuilder builder = factory.newDocumentBuilder(); 
     Document readLib = builder.parse(LIBRARY_FILE_PATH); 
     System.out.println("ID:" + id); 
     NodeList gameNodes = readLib.getElementsByTagName("Game"); 
     gameArray = new String[gameNodes.getLength()]; 
     for (int i = 0; i < gameNodes.getLength(); i++) { 
      Node p = gameNodes.item(i); 
      if (p.getNodeType() == Node.ELEMENT_NODE) { 
       Element Game = (Element) p; 
       String gameNames = Game.getAttribute("Name"); 
       gameArray[i] = gameNames; 
      } 
     } 
    } catch (ParserConfigurationException e) { 
     LogToFile.writeFile("[GM-Logging] Parser configuratoin exception when generating game list"); 
    } catch (SAXException e) { 
     LogToFile.writeFile("[GM-Logging] General SAXException in generateGames() method"); 
    } catch (IOException e) { 
     LogToFile.writeFile("[GM-Logging] IOException while generating game names in Library Manager engine"); 
    } 

Это пример того, что библиотека XML выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<Library> 
    <Playlist Id="0" list="First Person Shooters"> 
     <Game Name="Counter-Strike: Source"> 
      <Path>C:\\Program Files\\Games\\CSS\cstrike.exe</Path> 
      <Executable>cstrike.exe</Executable> 
     </Game> 
     <Game Name="Counter-Strike: Global Offense"> 
      <Path>C:\\Program Files\\Games\\CSGO\csgo.exe</Path> 
      <Executable>csgo.exe</Executable> 
     </Game> 
     <Game Name="Crysis 3"> 
      <Path>C:\\Program Files\\Games\\Crytek\crysislauncher.exe</Path> 
      <Executable>crysislauncher.exe</Executable> 
     </Game> 
    </Playlist> 
    <Playlist Id="1" list="Grand Theft Auto Series"> 
     <Game Name="Grand Theft Auto V"> 
      <Path>C:\\Program Files\\Games\\Rockstar\gtav.exe</Path> 
      <Executable>gtav.exe</Executable> 
     </Game> 
     <Game Name="Grand Theft Auto IV: Ballad of Gay Tony"> 
      <Path>C:\\Program Files\\Games\\Rockstar\gtaiv\gtaiv.exe</Path> 
      <Executable>gtaiv.exe</Executable> 
     </Game> 
    </Playlist> 
<Playlist Id="2" list="Survival and Horror Games"></Playlist> 

+0

Что версия Java вы используете, попробуйте использовать javax .xml.bind.JAXBContext, он будет анализировать создание объектов для вас –

+0

Java SE 8 Update 45, но я не совсем уверен, что вы имеете в виду – Nati0n

ответ

0

Я предлагаю заглянуть в xpath. Это поможет вам получить определенную часть XML, особенно если у вас более сложный фильтр, чем атрибут id. Я не ява парень, следующие коды, построенные на основе этого: How to read XML using XPath in Java:

DocumentBuilder builder = factory.newDocumentBuilder(); 
Document readLib = builder.parse(LIBRARY_FILE_PATH); 
XPathFactory xPathfactory = XPathFactory.newInstance(); 
XPath xpath = xPathfactory.newXPath(); 
XPathExpression expr = xpath.compile("//Playlist[@id='" + id + "']/Game"); 

System.out.println("ID:" + id); 
NodeList gameNodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET); 
//the rest can be the same code 
....... 

краткое объяснение о XPath используется:

Выше коды генерировать выражение XPath, который выглядит следующим образом:

//Playlist[@id='certain_id']/Game 
  • //Playlist: найти <Playlist> элементы в любом месте документа XML
  • [@id='certain_id']: фильтр вернуть только те, которые имеют id атрибут равен "certain_id"
  • /Game: от каждого из <Playlist> элемента, который удовлетворяет выше критерию, получить дочерний элемент <Game>
+0

Это то, что я закончил, и он отлично работал, спасибо! – Nati0n

0

Глядя на ваш XML, ниже мое предложение.

создать класс,

@XmlRootElement(name = "Library") 
public class Library { 
    private List<Playlist> playlist = new ArrayList<Playlist>(); 

..... getter 

@XmlElement(name = "Playlist") 
public void setPlaylist(List<Playlist> playlist) { 
     this.playlist = playlist; 
} 


@XmlRootElement(name = "Playlist") 
public class Playlist { 

private Game game; 
private String path; 
private String executable; 

@XmlElement(name = "path") 
public void setPath(String path) { 
     this.path = path; 
} 

... similarly write getter and setter for game & executable 


} 

@XmlRootElement(name = "Game") 
public class Game { 

private String name; 

@XmlElement(name = "name") 
public void setName(String name) { 
     this.name = name; 
} 

... write getter 


} 

в главном классе

JAXBContext jaxbContext = JAXBContext.newInstance(Library.class); 

      Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); 

String xmlStr = xmlString; // the entire xml as string 
      InputStream is = new ByteArrayInputStream(xmlStr.getBytes()); 

      Library library = (Library) jaxbUnmarshaller.unmarshal(is); 

      List<Playlist> playLst = library.getPlayList(); 

теперь у вас есть объект, который playLst разобранный XML

Смежные вопросы