Wie komme ich an die Siblings über DOM?

navino

Aktives Mitglied
Hallo,

ich versuche folgende Daten über DOM auszuwerten und komme nicht an die Werte für ZutatId.
Ich finde kein Beispiel für den Zugriff:

Code:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<zutaten>
  <zutat>
    <id>1</id>
    <name>Zucker</name>
    <notice>eine lange Bemerkung</notice>
    <inhaltstoffe>
        <ZutatId>4</ZutatId>
        <ZutatId>99</ZutatId>
    </inhaltstoffe>
  </zutat>
 
  <zutat>
    <id>2</id>
    <name>Mehl</name>
    <notice>eine lange Bemerkung für Mehl</notice>
    <inhaltstoffe>
        <ZutatId>12</ZutatId>
        <ZutatId>6</ZutatId>
        <ZutatId>7</ZutatId>
        <ZutatId>8</ZutatId>
        <ZutatId>9</ZutatId>
    </inhaltstoffe>
  </zutat>
</zutaten>
 

navino

Aktives Mitglied
Auf der Seite bin ich schon gewesen, da steht leider nicht welches xml-File benutzt wird, und verstehen tu ich das ehrlich gesagt auch nicht.
Das Usecase ist die Entwicklung eines Rezeptmanagers mit Java-Bordmitteln ohne Datenbank.
Ich habe mich jetzt für xml und DOM entschieden, muss ja auxh irgendwie gehen.
Das xml-File oben kann ich soweit auch lesen und in Objekte umwandeln. Nur an die ZutatenID's komme ich nicht dran. Da fehlt mir einfach die Syntax
 

Flown

Administrator
Mitarbeiter
Du hast dein Document Objekt und darauf wendest du dann document.getElementsByTagName("zutat") an. Damit erhälst du dann eine NodeList über die dann iterieren kannst:
Java:
public class Test {
  public static void main(String... args) {
    new Test().foo();
  }

  String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" +
    "<zutaten>\n" +
    "  <zutat>\n" +
    "    <id>1</id>\n" +
    "    <name>Zucker</name>\n" +
    "    <notice>eine lange Bemerkung</notice>\n" +
    "    <inhaltstoffe>\n" +
    "        <ZutatId>4</ZutatId>\n" +
    "        <ZutatId>99</ZutatId>\n" +
    "    </inhaltstoffe>\n" +
    "  </zutat>\n" +
    " \n" +
    "  <zutat>\n" +
    "    <id>2</id>\n" +
    "    <name>Mehl</name>\n" +
    "    <notice>eine lange Bemerkung für Mehl</notice>\n" +
    "    <inhaltstoffe>\n" +
    "        <ZutatId>12</ZutatId>\n" +
    "        <ZutatId>6</ZutatId>\n" +
    "        <ZutatId>7</ZutatId>\n" +
    "        <ZutatId>8</ZutatId>\n" +
    "        <ZutatId>9</ZutatId>\n" +
    "    </inhaltstoffe>\n" +
    "  </zutat>\n" +
    "</zutaten>";

  private void foo() {
    try {
      DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
      DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
      Document document = documentBuilder.parse(new InputSource(new StringReader(xml)));
      NodeList ingredients = document.getElementsByTagName("zutat");
      for (int i = 0; i < ingredients.getLength(); i++) {
        Element ingredient = (Element) ingredients.item(i);
        int id = Integer.parseInt(ingredient.getElementsByTagName("id").item(0).getTextContent());
        System.out.println(id);
      }
    } catch (SAXException | IOException | ParserConfigurationException e) {
      e.printStackTrace();
    }
  }
}
Mal ein Code zum ausführen.
 

Flown

Administrator
Mitarbeiter
Oder eben mit XPath:
Java:
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath();
NodeList paths = (NodeList) xPath.evaluate("//zutat/id/text()", document, XPathConstants.NODESET);
for (int i = 0; i < paths.getLength(); i++) {
  System.out.println(Integer.parseInt(paths.item(i).getNodeValue()));
}
 

navino

Aktives Mitglied
An die ID komme ich so, das ist auch nicht mein Problem dafür habe ich beispiele gefunden.
Ich benötige die Zutaten-Ids jeder Zutat (ZutatId). Die kommt aber mehrmals vor.
 

Flown

Administrator
Mitarbeiter
Alle ZutatenIds von allen Zutaten, oder per Zutat.

PS: Anders gefragt, wie soll die Liste aussehen für dein Beispiel XML?
 
Zuletzt bearbeitet:

Flown

Administrator
Mitarbeiter
Wäre wahrscheinlicher sauberer, wenn man JAXB oder so nehmen würde, aber per hand gehts nur so:
Java:
try {
  DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
  DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
  Document document = documentBuilder.parse(new InputSource(new StringReader(xml)));
  
  XPathFactory xPathFactory = XPathFactory.newInstance();
  XPath xPath = xPathFactory.newXPath();
  
  Map<Integer, List<Integer>> ingredientMapping = new HashMap<>();
  
  NodeList ingredients = (NodeList) xPath.evaluate("//zutat", document, XPathConstants.NODESET);
  for (int i = 0; i < ingredients.getLength(); i++) {
    Node ingredient = ingredients.item(i);
    int id = ((Number) xPath.evaluate("./id/text()", ingredient, XPathConstants.NUMBER)).intValue();
    NodeList ingredientsIds = (NodeList) xPath.evaluate(".//ZutatId/text()", ingredient, XPathConstants.NODESET);
    for (int j = 0; j < ingredientsIds.getLength(); j++) {
      Node ingredientId = ingredientsIds.item(j);
      ingredientMapping.computeIfAbsent(id, k -> new ArrayList<>()).add(Integer.parseInt(ingredientId.getNodeValue()));
    }
  }
  System.out.println(ingredientMapping);
} catch (SAXException | IOException | ParserConfigurationException | XPathExpressionException e) {
  e.printStackTrace();
}
}
 

navino

Aktives Mitglied
Hallo und Danke für das Beispiel, da wäre ich nie drauf gekommen.
Was besser ist ist mir hier egal, da ich die persitenz als xml vorgeben habe.
Normalerweise würde ich eine Datenbank nehmen !!

Danke für den Support !!!
 

Ähnliche Java Themen

Neue Themen


Oben