Posted Tue, 02 Jan 2018 20:35:50 GMT by Tom Depiera

Using the DocuWare Platform Service APIs, I've been able to retrieve documents' field values, however I am not able to retreive keyword field/values using this method. The documentation doesn't show a good example of what needs to be done in order to achieve this. 

 

I'm using the DocumentQueryResult method to return results.

 

Are there additional steps that need to be done in order to retreive keyword fields?

Posted Wed, 03 Jan 2018 18:15:00 GMT by Joe Kaufman Bell Laboratories Inc No longer there

I would also like to understand how to view Keyword values, both in the .NET environment as well as via straight Platform Service calls via non-.NET code (I can't get it to work in either -- only non-Keyword indexes come through).

I have non-.NET code that can SET keywords in a Keyword field -- just need to post correctly-formed XML (or JSON) against the resource:

/DocuWare/Platform/FileCabinets/{cab GUID}/Documents/{DWDOCID}/Fields

I searched the Platform Service URL Reference page for any mention of "keyword" and came up empty. 

It would be nice to have an example provided on how to access Keyword index types.

 

Thanks,

Joe Kaufman

PS. I realized the code to set Keyword indexes probably returns the keyword values in the response. But I am not sure how to just get the keywords as they are via something like a GET instead of a POST. EDIT: I confirmed that a successful update of keywords in a Keyword field returns an XML response that DOES contain the keyword field in addition to all the "regular" fields. I also confirmed the Keyword field is NOT included if I just to a straight search for a document and get an XML result back (non-.NET code).

 

Posted Wed, 03 Jan 2018 20:09:39 GMT by Tom Depiera

So I've made some progress with this, though i don't know for sure if I'm on the right track. I figured out that after I use a DocumentQueryResult to get the results of a dialog expression, You can iterate through the documents in the results and call the .GetDocumentFromSelfRelation() method on each. This returns the keyword fields as well as the others, however the DocumentIndexFieldKeywords class does not have a GetEnumerator() method, so I haven't been able to actually retrieve the values stored inside the keyword fields, thogh I can get the fieldLabel and fieldName properties. 

 

Here's what I've been working on, you just need to pass a DocumentQueryResult to the method and you should be able to see the actual keyword fieldNames listed. Any ideas how to get the values after this? I don't have a return type on the method yet because I'm still trying to figure out how to store and access the data, so I'm just printing out the info to the Console (.NET)

 

        public static void getKeywords(DocumentsQueryResult DocResults)
        {
            foreach (Document doc in DocResults.Items)
            {
                Document document = doc.GetDocumentFromSelfRelation();
                foreach (DocumentIndexField field in document.Fields)
                {
                    if(field.ItemElementName.ToString() == "Keywords" )
                    {
                        Console.WriteLine(field.FieldName);
                    }
                }
            }

        }

Posted Wed, 03 Jan 2018 20:10:51 GMT by Tom Depiera

Also, here's a link to more info from the documentation about the Keywords class: http://help.docuware.com/sdk/platform/html/P_DocuWare_Platform_ServerCli...

 

Posted Wed, 03 Jan 2018 20:42:40 GMT by Joe Kaufman Bell Laboratories Inc No longer there

Tom,

Excellent work, and you are almost there! The trick from there is to cast the "Item" property of the field (when you know it is a Keyword) to a DocumentIndexFieldKeywords type (which is built into the DocuWare .NET platform libs). Here is a foreach loop that extends your code to get just such an object (I bold-faced the line I added):

                foreach (Document doc in docs.Items)
                {
                    Document document = doc.GetDocumentFromSelfRelation();
                    foreach (DocumentIndexField field in document.Fields)
                    {
                        if (field.ItemElementName.ToString() == "Keywords")
                        {
                            DocumentIndexFieldKeywords keywords = (DocumentIndexFieldKeywords)field.Item;
                            Console.WriteLine(field.FieldName);
                        }
                    }
                }
 

The "keywords" variable (that is of type DocumentIndexFieldKeywords) has a property called "Keyword" that is a standard List<string>. So, you can get the count of the keywords via:

keywords.Keyword.Count

and would access the first string in the List via something like:

string firstKeyword = keywords.Keyword[0];

That should get you where you need to be.

It is very weird that you have to instantiate a second Document object via GetDocumentFromSelfRelation() when the items in the query result are already of type Document. Not sure if that is a bug or what. But I guess when in doubt, re-pull the document from its self-relation and get everything back that you need. From there, it is just a matter of casting the right property to the right type so it can be accessed without the compiler getting cranky or a run-time error being thrown.Just FYI, but if you try the above cast on a field that is not of the Keyword type, a run-time cast exception is thrown.

Thanks for working through this! Great info!

 

Thanks,

Joe Kaufman

 

 

Posted Wed, 03 Jan 2018 20:44:33 GMT by Joe Kaufman Bell Laboratories Inc No longer there

Yeah, that looks about right. Just hard to know what it all means without an example. I found the type by inspecting the variable, but that documentation would have told me straight away which type to cast into and that the "Keyword" property was a list of strings containing the results I ultimately wanted.

 

Thanks,

Joe Kaufman

Posted Wed, 03 Jan 2018 21:00:00 GMT by Tom Depiera

OK, I just added another foreach loop to iterate through the list and retreive the values. Seems like way too much work to get this data though. Next I'll work on storing key, value pairs in a dictionary.

 

 public static void getKeywords(DocumentsQueryResult DocResults)
        {
            foreach (Document doc in DocResults.Items)
            {
                Document document = doc.GetDocumentFromSelfRelation();
                foreach (DocumentIndexField field in document.Fields)
                {
                    if(field.ItemElementName.ToString() == "Keywords" )
                    {
                        DocumentIndexFieldKeywords keywords = (DocumentIndexFieldKeywords)field.Item;
                        foreach (var str in keywords.Keyword)
                        {
                            Console.WriteLine(str);
                        }

                    }
                }
            }

        }

 

Thanks for the help, I was spinning my wheels over this one. 

Posted Wed, 03 Jan 2018 21:12:10 GMT by Joe Kaufman Bell Laboratories Inc No longer there

Tom,

Looks good. Yeah, casting can be tricky with regard to seeing your way from point A to point B -- I am still not used to it, especially coming from Voisual Foxpro where there is no strict typing at all.

The foreach methodology isn't really all that onerous -- there's no other way, really, to iterate through a collection using procedural programming, whether it be an array, a list of strings, or rows in a DataTable.

If you do need to do more interesting things with a list of strings (or any IEnumerable), you can take a look at LINQ and other functional programming techniques. In many situations (a true LINQer might even say "all"), a foreach loop can be replaced with a single line of code. That line might be long and complicated, but LINQ lets you do set-based manipulation of enumerable elements without needing to use an explicit iterator construct.

Dictionaries are fun as well, just remember that you can't generally use the same key twice. When it comes to storing data in .NET apps, I tend to fall back on the good ol' DataTable type, another sign of my Foxpro origins where the cursor is supreme...

 

Thanks,

Joe Kaufman

You must be signed in to post in this forum.