Wie komme ich an die Siblings über DOM?

Diskutiere Wie komme ich an die Siblings über DOM? im XML und Co. Bereich.
N

navino

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>
 
N

navino

Das Beispiel ist mit JDom gemacht, das darf ich leider nicht benutzen
 
N

navino

Alles was im Java jdk erhalten ist.
Externe Bibliotheken sind nicht erlaubt.
 
N

navino

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

Flown

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

Flown

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()));
}
 
N

navino

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

Flown

In welcher Form benötigst du das Ergebnis. Alle ZustatenIds von einer Zutat?
 
Flown

Flown

Alle ZutatenIds von allen Zutaten, oder per Zutat.

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

navino

Ich benötige die ZutatId jeweils zur Zutat.
Danke schon einmal für die Unterstützung!!
 
Flown

Flown

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();
}
}
 
N

navino

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 !!!
 
Thema: 

Wie komme ich an die Siblings über DOM?

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben