четверг, 3 октября 2013 г.

Поменять значение в XML

Требуется поменять значение, спрятанное глубоко в XML.

<smev:RequestIdRef>{219F416E-4DB7-43DA-AFED-2EFFDD67C32A}</smev:RequestIdRef>



import org.apache.xpath.XPathAPI;

...



String respBody = "....";// XML
Element root = getXmlRoot(respBody);
Node requestIdRefNode = getXPath(root, "//*[local-name() = 'RequestIdRef']");
requestIdRefNode.setTextContent("New value");

public static final Element getXmlRoot(String xmlData) throws Exception
{
        // logger.info("Trying get root from: " + xmlData);
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        DocumentBuilder builder = factory.newDocumentBuilder();
        return builder.parse(new InputSource(new StringReader(xmlData))).getDocumentElement();
}

public static final Node getXPath(Element xmlData, String path) throws Exception

{
       Node nodes = null;    
       nodes = XPathAPI.selectSingleNode(xmlData,
                                 String.format("%s", path));
       return nodes;
 } 
Альтернативный способ, без использование XPathAPI:
    public static Document getXMLDocument(String xmlSource) throws Exception
    {
        DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = domFactory.newDocumentBuilder();
        return builder.parse(new InputSource(new StringReader(xmlSource)));
    }
 
    public static Node getXMLTagContent(Document document, String nodeExpression) throws XPathExpressionException
    {
        Node node = null;
        XPathFactory factory = XPathFactory.newInstance();
        XPath xpath = factory.newXPath();
        XPathExpression expression = xpath.compile(nodeExpression);
        if (document != null)
            node = (Node) expression.evaluate(document, XPathConstants.NODE);
        return node;
    }
 

4 комментария:

  1. Какое всё же стандартное XML API унылое говно :-(

    http://xom.nu - проще, быстрее, жрет меньше памяти

    Document doc = new Builder().build(new File("/temp/deep.xml"));//документ в памяти
    Nodes nodes = doc.getRootElement().query("/fuck/it/please/ns:RequestIdRef", new XPathContext("ns", "http://hardfuck.ru/deep"));//namespace можно вынести в константу
    Element el = (Element) nodes.get(0);//надо бы проверять что найдено
    assertEquals("{219F416E-4DB7-43DA-AFED-2EFFDD67C32A}", el.getValue());//просто показываю, что нашлось именно то что нужно
    el.removeChildren();//текст - это дети элемента
    el.appendChild("{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}");//к пустому элементу добавим новый текст
    System.out.println(doc.toXML());//видим что XML документ не изменился за исключением этой строки

    ОтветитьУдалить
    Ответы
    1. ps: быстрее и жрет меньше памяти проверялось года 2 назад, после этого не тестировал

      Удалить
  2. Этот комментарий был удален автором.

    ОтветитьУдалить