cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1837
Views
7
Helpful
5
Replies

IP IVR: Writing XML Document w/o Keyword Transform

michaelmiu
Level 1
Level 1

Hey Pros,

Can I write an xml document other than using the template file and keyword transform step?

I have too many values (1000+) to transform, it would take too long to enter them manually in the keyword transform step. I know there is an import function, however I still need to associate with local variable. It would be nice if I could utilize a loop and array, but I don't see how.

Thanks in advance.

5 Replies 5

vkapoor5
Level 5
Level 5

The extensible markup language (XML) application programming interface (API) provided by the router is an interface used for rapid development of client applications and perl scripts to manage and monitor the router. The XML interface is specified by the XML schemas. The XML API provides a mechanism for router configuration and monitoring utilizing an exchange of XML formatted request and response streams.

The following URL help you:

http://www.cisco.com/en/US/products/ps5845/products_programming_reference_guide_chapter09186a008076c7b3.html

bphelps
Level 2
Level 2

did you ever figure this out?

I couldn't figure an xml solution.

I ended up using the SQL Server database on the AW server to store the data.

This is an old thread but since it still turns up at the top of search results, including mine this morning, I wanted to share how I chose to solve this problem. What works for me may not work for you but it's better than nothing.

 

Problem: Both the Keyword Transform and XSL Transform Document step generate an entirely new XML file based on the Keyword template or XSL stylesheet respectively. Neither can accept an existing XML document (e.g. Document variable) as input and selectively modify it.

Solution: Pull the document value out into a string, parse it, and then concatenate it back together. Once complete, push it back to the document variable and re-run the Create XML Document step to force the value back through the XPath parser.

Caveats:

  • The element you are looking for still needs to be unique so you can find it within the String. This does NOT leverage the native Document Object Model handling that Java has. I started going down this road since it would be far more precise and efficient but ran into roadblocks. Namely, how to cast a org.w3c.dom.Document class value back into a com.cisco.doc.Document. I'm not a programmer by trade so this might be solvable by someone else.
    Examples of how to make it unique:
    • <my_unique_element_name></<my_unique_element_name>
      <!-- This has to be unique across the entire XML file, no repetition. -->
    • <generic_element_name id='myuid'></generic_element_name>
      <!-- This will make XML fans cringe less but comes at the cost of having to know the entire element character length. More on that in a moment. -->
  • Running this within a for/while loop embedded in a Do: step is possible but should be done with caution as you could trigger an infinite loop if not careful and crash the MIVR engine.
  • Probably other caveats I haven't yet thought of. As always, this information comes as-is without warranty. :)

{
  String localString = exampleDocument;
  int localStartIndex = localString.indexOf("<my_unique_element_name>");
  int localEndIndex = localString.indexOf("</my_unique_element_name>");
  // The localStartIndex+24 gets the first part of concatination to the end of the element name <my_unique_element_name>
  // The int value after the plus character should be adjusted based on the element name length, including open/close brackets.
  localString = localString.substring(0, localStartIndex+24) + "cisco" + localString.substring(localEndIndex);
  exampleDocument = TEXT[localString];
}

Hi Jonathan,

although the method you described works and I must admit it might even save a couple of CPU cycles (as text processing is generally assumed to be lighter than XML processing), I have to disagree with your approach. Java gives us nice adequate tools to perform XML processing in an elegant way. Let me demonstrate.

I created a simple XML file, named it simpledailymenu.xml, uploaded it to the Document repository. I am going to use it as the source document in my script.

<?xml version="1.0" encoding="UTF-8" ?>
<menu>
<choice calories="850">New York Strip Steak</choice>
<choice calories="250">Garden Salad</choice>
<choice calories="500">Wiener Schnitzli</choice>
<choice calories="370">Mamma's Minestrone</choice>
<choice calories="400">Caramelised Apples</choice>
</menu>

 

First, I am going to modify the text content of an element (Wiener Schnitzli is incorrect, so I am going to change it to the correct form, Wiener Schnitzel).

Second, I am going to modify the value of an attribute of an element. I think Caramelised Apples give you a bit more energy than 400 calories, let's adjust it to 510.

My script uses two variables, both of type Document, initial value DOC[]: oldDoc and newDoc. Theoretically speaking, one variable would be sufficient, too, I just wanted to keep things neat.

First, let's assign the value of oldDoc: Set oldDoc = DOC[simpledailymenu.xml]

Next, using a Set step we assign the value of newDoc, with this code block:

{
javax.xml.parsers.DocumentBuilderFactory dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance();
javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
org.w3c.dom.Document doc = db.parse(oldDoc.getInputStream());
org.w3c.dom.Node root = doc.getFirstChild();
// change text content of the third choice (canonically: 2) from "Wiener Schnitzli" to the correct form, "Wiener Schnitzel":
org.w3c.dom.Node secondChoice = doc.getElementsByTagName("choice").item(2);
secondChoice.setTextContent("Wiener Schnitzel");
// change the attribute "calories" of the last choice (Caramelised Apples) from 400 to 510:
int numChoices = doc.getElementsByTagName("choice").getLength();
org.w3c.dom.Node lastChoiceNode = doc.getElementsByTagName("choice").item(numChoices-1);
org.w3c.dom.Element lastChoiceElement = (org.w3c.dom.Element) lastChoiceNode; // we just assume lastChoiceNode is of type ELEMENT_NODE
lastChoiceElement.setAttribute("calories", "510");
javax.xml.transform.TransformerFactory tf = javax.xml.transform.TransformerFactory.newInstance();
javax.xml.transform.Transformer t = tf.newTransformer();
javax.xml.transform.dom.DOMSource source = new javax.xml.transform.dom.DOMSource(doc);
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
javax.xml.transform.stream.StreamResult result = new javax.xml.transform.stream.StreamResult(baos);
t.transform(source, result);
return (Document) baos.toByteArray();

// comment the above row and uncomment the following if you are affected by a strange bug:

// return baos.toString();
}

 

Remember, Documents are just arrays of bytes. In the context of UCCX scripting, you can create a Document just by passing a byte array.

G.

 

EDIT: Attached a screenshot of the script I tested this with.

Getting Started

Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community: