Question

j'ai un XmlDocument en java, créé avec le Weblogic XmlDocument analyseur.

Je souhaite remplacer le contenu d'une balise dans ce XMLDocument avec mes propres données, ou insérez la balise si elle n'est pas là.

<customdata>
   <tag1 />
   <tag2>mfkdslmlfkm</tag2>
   <location />
   <tag3 />
</customdata>

Je souhaite par exemple insérer une URL dans la balise de localisation :

<location>http://something</location>

mais sinon, laissez le XML tel quel.

Actuellement, j'utilise un XMLCursor:

    XmlObject xmlobj = XmlObject.Factory.parse(a.getCustomData(), options);
    XmlCursor xmlcur = xmlobj.newCursor();

    while (xmlcur.hasNextToken()) {
      boolean found = false;
      if (xmlcur.isStart() && "schema-location".equals(xmlcur.getName().toString())) {
        xmlcur.setTextValue("http://replaced");
        System.out.println("replaced");
        found = true;
      } else if (xmlcur.isStart() && "customdata".equals(xmlcur.getName().toString())) {
        xmlcur.push();
      } else if (xmlcur.isEnddoc()) {
        if (!found) {
          xmlcur.pop();
          xmlcur.toEndToken();
          xmlcur.insertElementWithText("schema-location", "http://inserted");
          System.out.println("inserted");
        }

      }
      xmlcur.toNextToken();
    }

J'ai essayé de trouver un "rapide" xquery façon de le faire depuis le XmlDocument a un execQuery méthode, mais je ne l'ai pas trouvé très facile.

Quelqu'un a-t-il un meilleur moyen que celui-ci ?Cela semble un peu élaboré.

Était-ce utile?

La solution

Que diriez-vous d’une approche basée sur XPath ?J'aime cette approche car la logique est très facile à comprendre.Le code est quasiment auto-documenté.

Si votre document XML est disponible en tant qu'objet org.w3c.dom.Document (comme le renvoient la plupart des analyseurs), vous pouvez alors faire quelque chose comme ce qui suit :

// get the list of customdata nodes
NodeList customDataNodeSet = findNodes(document, "//customdata" );

for (int i=0 ; i < customDataNodeSet.getLength() ; i++) {
  Node customDataNode = customDataNodeSet.item( i );

  // get the location nodes (if any) within this one customdata node
  NodeList locationNodeSet = findNodes(customDataNode, "location" );

  if (locationNodeSet.getLength() > 0) {
    // replace
    locationNodeSet.item( 0 ).setTextContent( "http://stackoverflow.com/" );
  }
  else {
    // insert
    Element newLocationNode = document.createElement( "location" );
    newLocationNode.setTextContent("http://stackoverflow.com/" );
    customDataNode.appendChild( newLocationNode );
  }
}

Et voici la méthode d'assistance findNodes qui effectue la recherche XPath.

private NodeList findNodes( Object obj, String xPathString )
  throws XPathExpressionException {

  XPath xPath = XPathFactory.newInstance().newXPath();
  XPathExpression expression = xPath.compile( xPathString );
  return (NodeList) expression.evaluate( obj, XPathConstants.NODESET );
}

Autres conseils

Que diriez-vous d’une approche orientée objet ?Vous pouvez désérialiser le XML en un objet, définir la valeur d'emplacement sur l'objet, puis le sérialiser en XML.

XStream rend cela vraiment facile.

Par exemple, vous définiriez l'objet principal, qui dans votre cas est CustomData (j'utilise des champs publics pour garder l'exemple simple) :

public class CustomData {
  public String tag1;
  public String tag2;
  public String location;
  public String tag3;
}

Ensuite, vous initialisez XStream :

XStream xstream = new XStream();
// if you need to output the main tag in lowercase, use the following line
xstream.alias("customdata", CustomData.class);  

Vous pouvez maintenant construire un objet à partir de XML, définir le champ d'emplacement sur l'objet et régénérer le XML :

CustomData d = (CustomData)xstream.fromXML(xml);
d.location = "http://stackoverflow.com";
xml = xstream.toXML(d);

Comment ça sonne?

Si vous ne connaissez pas le schéma, la solution XStream n'est probablement pas la solution.Au moins XStream est sur votre radar maintenant, cela pourrait s'avérer utile à l'avenir !

Vous devriez pouvoir le faire avec query

essayer

 fn:replace(string,pattern,replace)

Je suis moi-même nouveau sur xquery et j'ai trouvé que c'était un langage de requête difficile à utiliser, mais il fonctionne bien une fois que vous avez surmonté la courbe d'apprentissage initiale.

J'aimerais toujours qu'il y ait un moyen plus simple et aussi efficace ?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top