Cisco Support Community
cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Community 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.
Community 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.
Community 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

Community 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?

Community 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).

Community 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)
Community 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>

 

Community 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.
Community 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.
Community 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.

767
Views
54
Helpful
25
Replies
CreatePlease to create content