Cisco Support Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Announcements

Welcome to Cisco Support Community. We would love to have your feedback.

For an introduction to the new site, click here. And see here for current known issues.

Highlighted
New Member

UCCX check time of day (TOD) from XML file

I know how to do a basic holiday check from an XML file.  What I'd like to be able to do is check time of day (TOD) in an XML file.  For example if the CSQ is going to be closed for a half day on 12/24/17 I'd like to be able to enter this in my XML file.  Below is an example of how I could imagine entering the TOD info in an XML file (but I don't know if this is valid XML).  I'm thinking if I could read nested tags in the XML then I could read time values if they're entered for a holiday entry.

<?xml version="1.0" encoding="ISO-8859-1"?>
<Holidays>
       <Holiday1>12/24/17</Holiday1>
            <todStart>1200</todStart>
            <todEnd>1700</todEnd>
       <Holiday2>12/25/17</Holiday2>
       <Holiday3>12/30/17</Holiday3>
</Holidays>
2 ACCEPTED SOLUTIONS

Accepted Solutions

You're pretty close.  To nest

You're pretty close.  To nest your todStart and todEnd XML entities inside of Holiday1, it would look like this:

<Holiday1>
<todStart>1200</todStart>
<todEnd>1700</todEnd>
</Holiday1>

However, then you lose the actual date.  You cannot just keep it where it was now, you'll need to move it into a child element as well.

<Holiday1>
<date>12/24/17</date>
<todStart>1200</todStart>
<todEnd>1700</todEnd>
</Holiday1>

Then, in your script, you read the child todStart and todEnd after you've made a match on the holiday, and you try and convert (aka cast) them into Time objects.

This is a bit tricky, but one way I do this is like this, where start is a variable of type Time:

Set start = xmldata + " AM"

If you're using 24h format in your XML (E.g., 17:00:00), then the AM, will be ignored.  I.e., 0800 AM will work like expected, but 1700 AM will actually be 5:00 PM.  The reason to put it in there at all, is that it's required: either AM or PM.  And since 0800 PM actuall becomes 8:00 PM, we'll stick with AM.

Now, you need to compare the current time, to see if it's after the new start but before the new end.  We can do that with an If step like this:

If (T[now] >= start && T[now] < end)
    True
        /* Open */
    False
        /* Close */

You still have quite a bit of work to do in scripting to have the script read this new XML format, so post back if you have more questions.  E.g., You date is now in //Holiday1/date

I hope that helps.

Anthony Holloway

Please use the star ratings to help drive great content to the top of searches.
New Member

So how does the end user

So how does the end user change the xml file themselves? I haven't seen a process that would allow them to do this without them accessing the actual file. Then you need someone with xml knowledge. I have been using the application side to change the holiday dates, not an xml at all. It does require me to change the dates, but I dont touch the script.

John B.

25 REPLIES

You're pretty close.  To nest

You're pretty close.  To nest your todStart and todEnd XML entities inside of Holiday1, it would look like this:

<Holiday1>
<todStart>1200</todStart>
<todEnd>1700</todEnd>
</Holiday1>

However, then you lose the actual date.  You cannot just keep it where it was now, you'll need to move it into a child element as well.

<Holiday1>
<date>12/24/17</date>
<todStart>1200</todStart>
<todEnd>1700</todEnd>
</Holiday1>

Then, in your script, you read the child todStart and todEnd after you've made a match on the holiday, and you try and convert (aka cast) them into Time objects.

This is a bit tricky, but one way I do this is like this, where start is a variable of type Time:

Set start = xmldata + " AM"

If you're using 24h format in your XML (E.g., 17:00:00), then the AM, will be ignored.  I.e., 0800 AM will work like expected, but 1700 AM will actually be 5:00 PM.  The reason to put it in there at all, is that it's required: either AM or PM.  And since 0800 PM actuall becomes 8:00 PM, we'll stick with AM.

Now, you need to compare the current time, to see if it's after the new start but before the new end.  We can do that with an If step like this:

If (T[now] >= start && T[now] < end)
    True
        /* Open */
    False
        /* Close */

You still have quite a bit of work to do in scripting to have the script read this new XML format, so post back if you have more questions.  E.g., You date is now in //Holiday1/date

I hope that helps.

Anthony Holloway

Please use the star ratings to help drive great content to the top of searches.
New Member

I've always disagreed with

I've always disagreed with cisco holiday example.

in this example you need to work through holiday1 to holidayN

I always prefer it like below. Then you only make one XML call to see if today is a holiday, doing it like this makes it possible to do holidays several years in advance.

<Holidays>

<Holiday ID="12-24-2017">
<todStart>1200</todStart>
<todEnd>1700</todEnd>
</Holiday>

<Holiday ID="12-25-2017">
<todStart>1200</todStart>
<todEnd>1700</todEnd>
</Holiday>

</Holidays>

If you take it to the next step, you can also create them as <Holiday ID="12-25-any">, it only requires on more xml call, and now you have recurring dates.

/Christian

New Member

Christian, your reply is also

Christian, your reply is also super helpful.   I like the idea of of a single XML call and being able to create entries for years further out.  I'm just not sure exactly how you make that XML read call when using an ID. Is the "ID" a special XML keyword?  Would you show me an example of how to read it?

New Member

Sure thing,

Sure thing,

XML: <Holiday ID="12-24-2017">

Crs editor:"/descendant::Holidays/child::Holiday[attribute::ID='"+sDate+"']/child::todStart"

I can see in my own example I have a D in front: XML: <Holiday ID="D12-24-2017">

Can't recall if it's just for date or if it's needed for correct syntax (ID not starting with a number).

New Member

Thanks Christian.  I ended up

Thanks Christian.  I ended up with an XML file like this:

<?xml version="1.0" encoding="ISO-8859-1"?>
<Holidays>
<Holiday Date="1/18/17">
    <Active>true</Active>
    <StartTime>8:00 AM</StartTime>
    <EndTime>8:00 PM</EndTime>
</Holiday>
</Holidays>

Which I can read with either of these "Get XML Document Data" statements:

"/Holidays/Holiday[@Date='1/18/17']/Active"
"/Holidays/Holiday[@Date='" + todaysDate_str + "']/Active"

I return the value of "Active" to a boolean variable I check later to see if it's a holiday.  With the second example I set the string variable like this:

todaysDate_str = D[now] (ShortDdate)
New Member

Looking good :)

Looking good :)

and remember the job is never finished.

next could be expanding XML with more info like the prompt to read when a specific holiday is found:

<Holiday Date="1/18/17">
    <Active>true</Active>
    <StartTime>8:00 AM</StartTime>
    <EndTime>8:00 PM</EndTime>
    
<Prompt>DayOffJan.wav</Prompt>
</Holiday>

 

New Member

Good point.  I see that I can

Good point.  I see that I can add whatever data I want later and it won't affect my earlier scripts that reference this XML file, since they simply won't try to call whatever new tags I add.

Jim,

Jim,

Something similar was discussed here: https://supportforums.cisco.com/discussion/13160001/day-week-and-time-day-xml

In that discussion, finding the day of the week was desired. However, using a date instead of the day of week value might work (I haven't tested this). It may require a little modification of your code but it might work. I prefer using the syntax in the discussion rather than the /decendant:: method. For some reason, I can't seem to get that syntax right.

Also in that discussion, was a link to something Anthony Holloway wrote about handling time vaules which was quite helpful. You might find that useful as well.

I hope this helps.

Bill

Bill if you prefer that

Bill if you prefer that syntax, then just eleminate "Days" from the XPATH all together, since all of your Day elements are in it.

E.g.,

//Day[@ID="1"]/OpenTime

Versus

//Days/Day[@ID="1"/OpenTime

Even simpler!

The only time you would need to also put "Days" in the XPATH, is if you could potentially match the wrong Day element in your XML, but not in your example.

The double slash means "search" essentially, and saying "search" for the root element is kind of pointless, since it's a special elment which cannot be repeated, and therefore not needed to be searched for.

The following would have sufficed, and possibly have been easier on the processing:

/Days/Day[@ID="1"]/OpenTime

;)

Anthony Holloway

Please use the star ratings to help drive great content to the top of searches.

Thanks for the tip. I always

Thanks for the tip. I always learn something from your posts.

Bill

Much appreciated Bill!  Take

Much appreciated Bill!  Take care.

Anthony Holloway

Please use the star ratings to help drive great content to the top of searches.
New Member

Thanks Anthony for the very

Thanks Anthony for the very informative reply, it is very helpful.  I do have a few follow up questions though.

I was getting holiday dates like this:
dateFromFile = Get XML Document Data (holidayDoc, "/Holiday/" + holidayIncrement)

So with this new method would my call be like this:
dateStr = Get XML Document Data (holidayDoc, "/Holiday/" + holidayIncrement + "/date/")
todStartStr = Get XML Document Data (holidayDoc, "/Holiday/" + holidayIncrement + "/todStart/")
todEndStr = Get XML Document Data (holidayDoc, "/Holiday/" + holidayIncrement + "/todEnd/")

Would I need include TOD entries for all holidays or would the TOD strings simply get nothing returned to them (in which case I could easily check if the TOD reads were successful)?

As far as the time entry I'm not married to 2400 format.  Is it better/easier to use entries like "8:00 AM" and "5:00 PM"?

Your modifications look

Your modifications look correct.

I would recommend not putting in TOD for all holidays, and just checking for their existence.  If they're there, then you'll get the value, if not, then null.

So...

if (xmldata == null || xmldata.trim() == "")
    True
        /* TOD Not Found */
    False
        /* TOD Found */

I tend to use 24h format mostly, but I don't see any reason you couldn't use 12h, and specifying the am/pm.

Anthony Holloway

Please use the star ratings to help drive great content to the top of searches.
New Member

I primarily used a

I primarily used a combination of Anythony's and Christian's replies to create my solution, but I don't think I can mark more than one post as the correct answer, so I went with Anthony's first reply as the "Correct Answer" post.

Checking for null and "" works to catch missing TOD entries.

I also added two On Exception  Goto statements:

  1. ExpressionException catches time formatting issues like 8:00AM (with no space before the AM)
  2. DocumentException catches general XML formatting issues (like forgetting a closing tag)

One other thing I did slightly different was instead taking the XML time and storing it in a time object I cast the time string to a time object in my if statement like this:

If (T[now] >= T[xmlStart_str] && T[now] < T[xmlEnd_str])
    True
        /* Open */
    False
        /* Close */

Thanks to all that replied.  I found all the info this this thread very helpful.

Right on.  I like your

Right on.  I like your inclusion of the Exception handler.  Have you seen this:

https://supportforums.cisco.com/document/112046/uccx-discovering-exceptions

Anthony Holloway

Please use the star ratings to help drive great content to the top of searches.
New Member

Wow, I didn't know there used

Wow, I didn't know there used to be so many different types of exceptions!  I'm using 10.6, I've never tried using On Exception with earlier versions of UCCX.  Excellent doc (and script), thank you for sharing.

New Member

Do you have to have the

Do you have to have the holiday and time of day settings in an XML file? Is something auto-generating the file for you?

I have created a holiday sub-script for all of my main scripts that not only determines if it is a holiday for the specific application (departments have different holidays), but also plays the prompt stating what holiday the department is closed for (using TTS). Since this sub-script is associated with an application, I just change the holiday application one a year. I'm thinking the time of day could be set in this application as well and then that variable could be brought over only when necessary for the individual application. This would eliminate the use of xml documents all together.

Of course, there are always about 5 different ways to get the same result in scripting.

New Member

Thanks for the reply and

Thanks for the reply and additional point of view.  I wouldn't have to use XML files.  It seems like XML will cause me more initial pain to get it working, but once I've got it working I assume that editing/adding an XML file won't be any harder than editing a list of dates in a script.

Additionally, one part of my grand master plan for world domination includes giving the caller the ability to write to an XML file to schedule call center closures themselves.  So if I need to check an XML for some of the closure logic I thought it best to keep all of my closure info in XML files.

If there's something inherently bad about using XML files I could be talked out of it (but then I don't know how I'd give callers the ability to schedule manual closures themselves).

New Member

I would always place data out

I would always place data out of the script - for the same reason as you have: Ease of admin for the customers. Having stuff like opening hours and holidays directly in the script is not scaleable or manageable by the customer.

If you want to make it even easier make a front end to those XML files.

New Member

So how does the end user

So how does the end user change the xml file themselves? I haven't seen a process that would allow them to do this without them accessing the actual file. Then you need someone with xml knowledge. I have been using the application side to change the holiday dates, not an xml at all. It does require me to change the dates, but I dont touch the script.

John B.

New Member

Could be a webserver,

Could be a webserver, generating xml files based on database or Excel saved to XML and put on webserver or uploaded via /appadmin.

Personal preference is having a webservice to feed CCX via XML

New Member

I plan on using a separate

I plan on using a separate script to allow the user to call in and schedule the activation.  In my plan this will require a separate "manual" XML file.  This is a phase 2 project for me, so I haven't worked on it yet.  I'm sure the other UCCX gurus here have much cooler ways of doing this, so if anyone else has a better way they want to share I'm all ears.  :)

New Member

I do use CCX "tools"

I do use CCX "tools" applications where users call in and change the closed reason or even change prompts on the fly, all using changes to the xml or actual prompts. It works well.

I just didn't know if anyone had a process that did not include the end-user messing around with the raw file. Most people here can't spell xml.

New Member

Using webservice to do it

Using webservice to do it without messing around in raw data

Setting data:

GUI/frontend webservice - (SQL)> Database

CCX http call -> Webservice -(SQL)> Database 

Getting Data:

CCX Get xml-(XML)> Webservice -(SQL)> Database  

And doesn't take much of a developler to create a simple page for opening and closing hours.

New Member

Re: I do use CCX "tools"

Hi,

 

I've trying to figure this out myself and I see you have it working.

 

Do you mind sharing how you made the work. There are times the agents go into meeting and agent in not ready state or log out. I 'd like for them to be able to call a number to open and meeting.

359
Views
54
Helpful
25
Replies