如何从Java中将子元素从XML提取到字符串?

时间:2009-03-10 20:05:16

标签: java xml

如果我有像

这样的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 个答案:

答案 0 :(得分:7)

你是对的,使用标准的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()获得第一个孩子,但问题是如果root和child元素之间有任何空格,那将创建一个Text树中的节点,您将获得该节点而不是实际的元素节点。该程序的输出是:

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

我认为如果你不需要它可以抑制xml版本字符串,但我不确定。如果可能的话,我可能会尝试使用第三方XML库。

答案 1 :(得分:5)

因为这是谷歌的最佳答案,对于那些只想要基本的人来说:

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

我用它进行调试,这很可能是你需要的

答案 2 :(得分:3)

我会推荐JDOM。它是一个Java XML库,它使得处理XML比标准的W3C方法更容易。

答案 3 :(得分:1)

XMLBeans是一个易于使用的工具(一旦掌握它),可以处理XML而无需处理解析的烦恼。

它要求您拥有XML文件的架构,但它还提供了一个工具,用于从exisint XML文件生成架构(根据您的需要,生成的内容可能很好)。

答案 4 :(得分:0)

如果你的xml有架构支持它,你可以使用xmlbeans或JAXB来生成pojo对象,帮助你编组/解组xml。

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

答案 5 :(得分:0)

由于问题实际上是关于第一次出现在另一个字符串中的字符串,我会使用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);
}

答案 6 :(得分:0)

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作为字符串传递给此方法,并在您的情况下传递&#39;元素&#39;作为参数标记名。

答案 7 :(得分:0)

您可以使用以下函数通过传递正确的xpath表达式

将xml块提取为字符串
    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));

}