android XPath,将节点从一个文档复制到另一个文档

发布于 2024-12-05 19:12:50 字数 1183 浏览 6 评论 0原文

您好,我需要将节点从一个 XML 复制到另一个 XML:

String _sPathOfrObj = "/response/grp/ofr/obj";
String _sPathHotelData = "/main/hotelData";
String _sPathStatus = "/main/status";
xpath.reset();
NodeList status = (NodeList) xpath.evaluate( _sPathStatus, details, XPathConstants.NODESET );
if(status.item( 0 ).getTextContent().equalsIgnoreCase( "ok" ))
{
    NodeList nodes3 = (NodeList) xpath.evaluate( _sPathOfrObj, result, XPathConstants.NODESET );
    NodeList nodes4 = (NodeList) xpath.evaluate( _sPathHotelData, details, XPathConstants.NODESET);
    minimum = Math.min( nodes3.getLength(), nodes4.getLength() );

    Log.i(CLASS_NAME, "obj="+nodes3.getLength());
    Log.i(CLASS_NAME, "hdat="+nodes4.getLength());

    for (i = 0; i < minimum; i++)
    {
        try
        {
            nodes3.item( i ).appendChild( nodes4.item( i ) );
        }
        catch(DOMException dome)
        {
            dome.printStackTrace();
            Log.e(CLASS_NAME, dome.code+"" );
        }
    }
}

但它会生成错误 DOMException WRONG_DOCUMENT_ERR 或者当我执行 nodes4.item( i ).deepClone(true or false) 时,它将抛出 DOMException NAMESPACE_ERR

有办法做到吗?

非常感谢

Hi I need to copy nodes from one XML into another one:

String _sPathOfrObj = "/response/grp/ofr/obj";
String _sPathHotelData = "/main/hotelData";
String _sPathStatus = "/main/status";
xpath.reset();
NodeList status = (NodeList) xpath.evaluate( _sPathStatus, details, XPathConstants.NODESET );
if(status.item( 0 ).getTextContent().equalsIgnoreCase( "ok" ))
{
    NodeList nodes3 = (NodeList) xpath.evaluate( _sPathOfrObj, result, XPathConstants.NODESET );
    NodeList nodes4 = (NodeList) xpath.evaluate( _sPathHotelData, details, XPathConstants.NODESET);
    minimum = Math.min( nodes3.getLength(), nodes4.getLength() );

    Log.i(CLASS_NAME, "obj="+nodes3.getLength());
    Log.i(CLASS_NAME, "hdat="+nodes4.getLength());

    for (i = 0; i < minimum; i++)
    {
        try
        {
            nodes3.item( i ).appendChild( nodes4.item( i ) );
        }
        catch(DOMException dome)
        {
            dome.printStackTrace();
            Log.e(CLASS_NAME, dome.code+"" );
        }
    }
}

but it generates an error, DOMException WRONG_DOCUMENT_ERR or when I will do nodes4.item( i ).deepClone(true or false) it will throw DOMException NAMESPACE_ERR

Is there a way to do it?

Many thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

本宫微胖 2024-12-12 19:12:50

我已经成功地让它工作了,它是我克服 deepClone 抛出 NAMESPACE_ERR 的解决方案和 链接

基本上我无法在没有错误的情况下复制给定节点,因此我将 XML 展平为字符串并将字符串转换为新节点,并通过使用领养节点我得到了我的解决方案:)

我确实意识到这是地狱一个 hack,但它适用于我紧迫的期限:)

转换为字符串是通过使用 Transformer 类完成的,如下所示:

private static final String CLASS_NAME = "SendQueryTask";
//...
import java.io.StringWriter;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
//...
private String transformXmlToString(Node node)
{
    Transformer transformer = null;
    try
    {
        transformer = TransformerFactory.newInstance().newTransformer();
    }
    catch (TransformerConfigurationException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    catch (TransformerFactoryConfigurationError e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    if ( transformer != null )
    {
        transformer.setOutputProperty( OutputKeys.INDENT, "yes" );

        // initialize StreamResult with File object to save to file
        StreamResult result = new StreamResult( new StringWriter() );
        DOMSource source = new DOMSource( node );

        try
        {
            transformer.transform( source, result );
        }
        catch (TransformerException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        String xmlString = result.getWriter().toString();
        Log.i( CLASS_NAME, "flattened=" + (xmlString) );

        return xmlString;
    }       
    return null;
}

并将其转换回 Node

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.http.protocol.HTTP;
import java.io.UnsupportedEncodingException;

private Node dumbNodeCopy(Node item)
{
    String xmlString = transformXmlToString( item );

    if ( xmlString != null )
    {
        InputStream is = null;
        try
        {
            is = new ByteArrayInputStream( xmlString.getBytes( HTTP.UTF_8 ) );
        }
        catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }

        if ( is != null )
        {
            Document doc = null;
            dbf = DocumentBuilderFactory.newInstance();
            try
            {
                db = dbf.newDocumentBuilder();
                doc = db.parse( is );
                doc.getDocumentElement().normalize();

            }
            catch (ParserConfigurationException e)
            {
                e.printStackTrace();
            }
            catch (SAXException e)
            {
                e.printStackTrace();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }

            if ( doc != null ) return doc.getFirstChild();
        }
        return null;
    }
    return null;

,最后进行复制

NodeList nodes3 = (NodeList) xpath.evaluate( _sPathOfrObj, result,
        XPathConstants.NODESET );
NodeList nodes4 = (NodeList) xpath.evaluate( _sPathHotelData, details,
        XPathConstants.NODESET );
minimum = Math.min( nodes3.getLength(), nodes4.getLength() );

Log.i( CLASS_NAME, "obj=" + nodes3.getLength() );
Log.i( CLASS_NAME, "hdat=" + nodes4.getLength() );

for (i = 0; i < minimum; i++)
{
    try
    {
        Node copy = dumbNodeCopy( nodes4.item( i ) );
        if ( copy != null )
        {
            // nodes3.item( i ).appendChild( copy );
            nodes3.item( i ).appendChild(
                    nodes3.item( i ).getOwnerDocument().adoptNode( copy ) );
        }
        else
            Log.e( CLASS_NAME, "Copy of nodes4#" + i + ", failed." );
    }
    catch (DOMException dome)
    {
        dome.printStackTrace();
        Log.e( CLASS_NAME, dome.code + "" );
    }
}

。不要嘲笑代码:-) 我知道它看起来很糟糕,但我的当务之急是按时完成 ATM,如果有人提出巧妙的解决方案,我会很乐意遵守:)

I've managed to have it working, it is a mixture of my solution to overcome deepClone throwing NAMESPACE_ERR and the solution presented in the link.

Basically I wasn't able to make a copy of the given node without an error so I am flattening the XML to string and converting the string to new Node and by using the adoptNode I have my solution:)

I do realise that it is hell of a hack but it works for my tight deadline:)

The converting to string is done by using Transformer class as follows:

private static final String CLASS_NAME = "SendQueryTask";
//...
import java.io.StringWriter;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
//...
private String transformXmlToString(Node node)
{
    Transformer transformer = null;
    try
    {
        transformer = TransformerFactory.newInstance().newTransformer();
    }
    catch (TransformerConfigurationException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    catch (TransformerFactoryConfigurationError e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    if ( transformer != null )
    {
        transformer.setOutputProperty( OutputKeys.INDENT, "yes" );

        // initialize StreamResult with File object to save to file
        StreamResult result = new StreamResult( new StringWriter() );
        DOMSource source = new DOMSource( node );

        try
        {
            transformer.transform( source, result );
        }
        catch (TransformerException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        String xmlString = result.getWriter().toString();
        Log.i( CLASS_NAME, "flattened=" + (xmlString) );

        return xmlString;
    }       
    return null;
}

and to convert it back to Node

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.http.protocol.HTTP;
import java.io.UnsupportedEncodingException;

private Node dumbNodeCopy(Node item)
{
    String xmlString = transformXmlToString( item );

    if ( xmlString != null )
    {
        InputStream is = null;
        try
        {
            is = new ByteArrayInputStream( xmlString.getBytes( HTTP.UTF_8 ) );
        }
        catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }

        if ( is != null )
        {
            Document doc = null;
            dbf = DocumentBuilderFactory.newInstance();
            try
            {
                db = dbf.newDocumentBuilder();
                doc = db.parse( is );
                doc.getDocumentElement().normalize();

            }
            catch (ParserConfigurationException e)
            {
                e.printStackTrace();
            }
            catch (SAXException e)
            {
                e.printStackTrace();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }

            if ( doc != null ) return doc.getFirstChild();
        }
        return null;
    }
    return null;

and finally the copying

NodeList nodes3 = (NodeList) xpath.evaluate( _sPathOfrObj, result,
        XPathConstants.NODESET );
NodeList nodes4 = (NodeList) xpath.evaluate( _sPathHotelData, details,
        XPathConstants.NODESET );
minimum = Math.min( nodes3.getLength(), nodes4.getLength() );

Log.i( CLASS_NAME, "obj=" + nodes3.getLength() );
Log.i( CLASS_NAME, "hdat=" + nodes4.getLength() );

for (i = 0; i < minimum; i++)
{
    try
    {
        Node copy = dumbNodeCopy( nodes4.item( i ) );
        if ( copy != null )
        {
            // nodes3.item( i ).appendChild( copy );
            nodes3.item( i ).appendChild(
                    nodes3.item( i ).getOwnerDocument().adoptNode( copy ) );
        }
        else
            Log.e( CLASS_NAME, "Copy of nodes4#" + i + ", failed." );
    }
    catch (DOMException dome)
    {
        dome.printStackTrace();
        Log.e( CLASS_NAME, dome.code + "" );
    }
}

btw. don't laugh at the code:-) I know that it looks terrible but my imperative ATM is to meet deadlines, and if anyone will propose neat solution I will happily adhere:)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文