Pregunta

tengo un XmlDocument en java, creado con el Weblogic XmlDocument analizador.

Quiero reemplazar el contenido de una etiqueta en este XMLDocument con mis propios datos, o insertar la etiqueta si no está ahí.

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

Por ejemplo, quiero insertar alguna URL en la etiqueta de ubicación:

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

pero por lo demás deja el XML como está.

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

Intenté encontrar un "rápido" xquery manera de hacer esto desde el XmlDocument tiene un execQuery método, pero no lo encontré muy fácil.

¿Alguien tiene una manera mejor que esta?Parece un poco elaborado.

¿Fue útil?

Solución

¿Qué tal un enfoque basado en XPath?Me gusta este enfoque porque la lógica es muy fácil de entender.El código es prácticamente autodocumentado.

Si su documento xml está disponible como un objeto org.w3c.dom.Document (como lo hacen la mayoría de los analizadores), entonces podría hacer algo como lo siguiente:

// 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 );
  }
}

Y aquí está el método auxiliar findNodes que realiza la búsqueda 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 );
}

Otros consejos

¿Qué tal un enfoque orientado a objetos?Puede deserializar el XML a un objeto, establecer el valor de ubicación en el objeto y luego volver a serializarlo a XML.

XStream hace que esto sea realmente fácil.

Por ejemplo, definirías el objeto principal, que en tu caso es CustomData (estoy usando campos públicos para mantener el ejemplo simple):

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

Luego inicializas XStream:

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

Ahora puedes construir un objeto a partir de XML, establecer el campo de ubicación en el objeto y regenerar el XML:

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

¿Como suena eso?

Si no conoce el esquema, la solución XStream probablemente no sea el camino a seguir.Al menos XStream está en tu radar ahora, ¡podría resultarte útil en el futuro!

Deberías poder hacer esto con query

intentar

 fn:replace(string,pattern,replace)

Soy nuevo en xquery y he descubierto que es un lenguaje de consulta complicado para trabajar, pero funciona bastante bien una vez que se supera la curva de aprendizaje inicial.

¿Todavía desearía que hubiera una manera más fácil y eficiente?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top