Как извлечь дочерний элемент из XML в строку в Java? - PullRequest
7 голосов
/ 10 марта 2009

Если у меня есть XML-документ, такой как

<root>   
   <element1>
        <child attr1="blah">
           <child2>blahblah</child2>
        <child>   
   </element1> 
</root>

Я хочу получить строку XML с первым дочерним элементом. Моя строка вывода будет

<element1>
    <child attr1="blah">
       <child2>blahblah</child2>
    <child>
</element1>

Есть много подходов, хотелось бы увидеть некоторые идеи. Я пытался использовать Java XML API для этого, но не ясно, есть ли хороший способ сделать это.

спасибо

Ответы [ 8 ]

7 голосов
/ 11 марта 2009

Вы правы, со стандартным XML API, нет хорошего пути - вот один пример (может быть с ошибками; он работает, но я написал это давно).

import javax.xml.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import org.w3c.dom.*;
import java.io.*;

public class Proc
{
    public static void main(String[] args) throws Exception
    {
        //Parse the input document
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(new File("in.xml"));

        //Set up the transformer to write the output string
        TransformerFactory tFactory = TransformerFactory.newInstance();
        Transformer transformer = tFactory.newTransformer();
        transformer.setOutputProperty("indent", "yes");
        StringWriter sw = new StringWriter();
        StreamResult result = new StreamResult(sw);

        //Find the first child node - this could be done with xpath as well
        NodeList nl = doc.getDocumentElement().getChildNodes();
        DOMSource source = null;
        for(int x = 0;x < nl.getLength();x++)
        {
            Node e = nl.item(x);
            if(e instanceof Element)
            {
                source = new DOMSource(e);
                break;
            }
        }

        //Do the transformation and output
        transformer.transform(source, result);
        System.out.println(sw.toString());
    }
}

Может показаться, что вы можете получить первого потомка, просто используя doc.getDocumentElement (). GetFirstChild (), но проблема в том, что если между корневым элементом и дочерним элементом есть пробел, это создаст текст узел в дереве, и вы получите этот узел вместо фактического элемента узла. Выход из этой программы:

D:\home\tmp\xml>java Proc
<?xml version="1.0" encoding="UTF-8"?>
<element1>
        <child attr1="blah">
           <child2>blahblah</child2>
       </child>
   </element1>

Я думаю, что вы можете подавить строку версии XML, если она вам не нужна, но я не уверен в этом. Вероятно, я бы попытался использовать стороннюю библиотеку XML, если это вообще возможно.

5 голосов
/ 15 мая 2012

Так как это топовый ответ Google и для тех из вас, кто просто хочет базовое:

    public static String serializeXml(Element element) throws Exception
{
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    StreamResult result = new StreamResult(buffer);

    DOMSource source = new DOMSource(element);
    TransformerFactory.newInstance().newTransformer().transform(source, result);

    return new String(buffer.toByteArray());
}

Я использую это для отладки, что, скорее всего, то, что вам нужно для

3 голосов
/ 10 марта 2009

Я бы порекомендовал JDOM . Это библиотека Java XML, которая делает работу с XML намного проще, чем стандартный подход W3C.

1 голос
/ 11 марта 2009

XMLBeans - это простой в использовании (как только вы его освоите) инструмент для работы с XML без необходимости разбираться с неприятностями при разборе.

Требуется, чтобы у вас была схема для XML-файла, но также имеется инструмент для создания схемы из существующего XML-файла (в зависимости от ваших потребностей сгенерированный файл, вероятно, подходит).

0 голосов
/ 14 сентября 2017

Вы можете использовать следующую функцию, чтобы извлечь блок xml в виде строки, передав правильное выражение xpath,

    private static String nodeToString(Node node) throws TransformerException
{
    StringWriter buf = new StringWriter();
    Transformer xform = TransformerFactory.newInstance().newTransformer();
    xform.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
    xform.transform(new DOMSource(node), new StreamResult(buf));
    return(buf.toString());
}

    public static void main(String[] args) throws Exception
{
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
        Document doc = dBuilder.parse(inputFile);

        XPath xPath = XPathFactory.newInstance().newXPath();
        Node result = (Node)xPath.evaluate("A/B/C", doc, XPathConstants.NODE); //"A/B[id = '1']" //"//*[@type='t1']"

        System.out.println(nodeToString(result));

}
0 голосов
/ 09 августа 2017
public String getXML(String xmlContent, String tagName){

    String startTag = "<"+ tagName + ">";
    String endTag = "</"+ tagName + ">";
    int startposition = xmlContent.indexOf(startTag);
    int endposition = xmlContent.indexOf(endTag, startposition);
    if (startposition == -1){
        return "ddd";
    }
    startposition += startTag.length();
    if(endposition == -1){ 
        return "eee";
    }
    return xmlContent.substring(startposition, endposition);
}

Передайте ваш xml как строку этому методу, а в вашем случае передайте 'element' в качестве параметра tagname.

0 голосов
/ 18 июня 2016

Поскольку вопрос фактически касается первого появления строки внутри другой строки, я бы использовал методы класса String вместо синтаксических анализаторов XML:

public static String getElementAsString(String xml, String tagName){
    int beginIndex = xml.indexOf("<" + tagName);
    int endIndex = xml.indexOf("</" + tagName, beginIndex) + tagName.length() + 3;
    return xml.substring(beginIndex, endIndex);
}
0 голосов
/ 10 марта 2009

Если ваша xml поддерживает схему, вы можете использовать xmlbeans или JAXB для генерации объектов pojo, которые помогут вам маршалировать / unmarshal xml.

http://xmlbeans.apache.org/ https://jaxb.dev.java.net/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...