Forum Discussion

Testranger's avatar
Testranger
Contributor
14 years ago

Insert XML fragment into request object

Hi all,

I have a requirement to insert a parsed XML fragment into a request object.

The parsed XML looks something like this (not exact fragment)
<s:comparable xmlns:s="http://www.w3.org/HTML/1998/html4"
xmlns:xdc="http://www.xml.com/books">
<xdc:transfer>
<xdc:price>$100.00</xdc:price>
<xdc:price>$200.00</xdc:price>
</xdc:transfer>
</s:comparable>

Using groovy, I parse this, using Transformers, StringWriters, etc and store it into a test case property.

Using groovy again, I create a "placement marker" inside the request object. Like:

<s:envelope xmlns:s="http://www.w3.org/HTML/1998/html4"
xmlns:xdc="http://www.xml.com/books">
...
<s:comparable/>
...
</s:envelope>


Using the property transfer feature i create an xpath transfer from the test case property to the request object. It seems to work. The following is created:

<s:envelope xmlns:s="http://www.w3.org/HTML/1998/html4"
xmlns:xdc="http://www.xml.com/books">
...
<s:comparable>
<xdc:transfer>
<xdc:price>$100.00</xdc:price>
<xdc:price>$200.00</xdc:price>
</xdc:transfer>
</s:comparable>
...
</s:envelope>

Note: in property transfer, I have selected "transfer child nodes".


Basically, what I'd like to know is, is there a better way of doing this? Do i even need to use property transfer?
Thanks in advance.

Regards,
Testranger

12 Replies

  • M_McDonald's avatar
    M_McDonald
    Super Contributor
    Actually the requestXml XmlSlurper object has the whole request, and you can navigate to whatever node you need, for example:

    requestXml.toplevel.nextlevel.updateRequest.appendNode( toAddXml.reference )

    So you have the whole request to do the replace with. Unless I've misunderstood.
  • What you've suggested looks too simple to be true. Will try it.

    For the time being though will use the following approaches as they seem to work for both insert scenarios I'm using

    1. For inserting a whole fragment
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true)
    DocumentBuilder builderFrag = dbf.newDocumentBuilder();
    Document docFrag = builderFrag.parse(new InputSource(new StringReader(xmlString)));
    Element elementDocFrag = docFrag.getDocumentElement();
    //log.info elementDocFrag

    //append comparable xml text above to order
    def comparableNode = requestHolder.getDomNode("//ns22:updateRequest[1]/ns22:data[1]/ns18:comparableSale[5]")
    if (comparableNode == null) {
    Node tempNode2 = requestDoc.importNode(elementDocFrag, true);
    Transformer transformer2 = TransformerFactory.newInstance().newTransformer();
    StringWriter sw2 = new StringWriter();
    transformer2.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
    transformer2.transform(new DOMSource(tempNode2), new StreamResult(sw2));
    //log.info sw2.toString()
    requestNode.appendChild(tempNode2)
    requestHolder.updateProperty(true)
    }


    2. For iterating/inserting children of a fragment
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true)
    DocumentBuilder builderFrag = dbf.newDocumentBuilder();
    Document docFrag = builderFrag.parse(new InputSource(new StringReader(xmlString)));
    Element elementDocFrag = docFrag.getDocumentElement();
    //log.info elementDocFrag

    //NodeList children = elementDocFrag.getChildNodes();
    //log.info "There are "+children.getLength()+" child elements."
    def nodeReference = requestHolder.getDomNode("//ns22:updateRequest[1]/ns22:data[1]/ns18:riskAnalysis[1]")
    if (nodeReference == null) {
    for (Node child = elementDocFrag.getFirstChild();child != null;child = child.getNextSibling()) {
    if (child.getNodeType() == child.TEXT_NODE){
    //log.info "Text: "+child.getNodeValue()
    } else if (child.getNodeType() == child.ELEMENT_NODE) {
    Node tempNode = requestDoc.importNode(child, true);
    Transformer transformer = TransformerFactory.newInstance().newTransformer();
    StringWriter sw = new StringWriter();
    transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
    transformer.transform(new DOMSource(tempNode), new StreamResult(sw));
    //log.info sw.toString()
    requestNode.appendChild(tempNode)
    }
    }
    requestHolder.updateProperty(true)
    }

    Thanks for the help.

    Best Regards,
    Testranger