Introduction
This documents provides a brief introduction into the Congree REST API. It is a step-by-step guide detailling all steps that are required to use the API successfully within third-party applications.
The document assumes a basic knowledge of C# and the principles of REST.
Getting an authentication token
To be able to use the functionality provided in the REST API it is necessary to obtain an authentication token that will be used in all of the requests dedicated to do linguistics checks.
In this section we will be creating a class that does all the work for us. The basic skeleton of the class is shown in the listing below:
using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Text; using System.Threading.Tasks; namespace CongreeRestApiTutorial { class CongreeHttpClient { private string authUrl = "/congreeidentityserver/connect/token"; public CongreeHttpClient(string serverUrl) { this.authUrl = serverUrl + this.authUrl; } } }
The constructor expects as single argument which is the base url of the server where Congree is installed, e.g. http://localhost.
Wihtin the constructor the argument is being concatenated with the contents of the class varibale authurl, to produce an URL like http://localhost/congreeidentityserver/connect/token.
In the next step we add a method that returns a authentication token. The method accepts to arguments: the user's username and his password. If the password is empty an empty string is being passed.
To allow for an easier access to the JSON object returned from the server the sample below uses a helper class "AccessToken" that is being used to deserialize the JSON object to a C# object.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CongreeRestApiTutorial { public class AccessToken { public string access_token { get; set; } public string expires_in { get; set; } public AccessToken() { } } }
The class shown above is being used as the target for the serialization of the JSON object using the tools from Newtonsoft.Json.
The code below uses RestSharp. You may want to add this package to your project as well.
using Newtonsoft.Json; using RestSharp; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Text; using System.Threading.Tasks; namespace CongreeRestApiTutorial { class CongreeHttpClient { private string authUrl = "/congreeidentityserver/connect/token"; public CongreeHttpClient(string serverUrl) { this.authUrl = serverUrl + this.authUrl; } public string GetToken(string username, string password) { string token = ""; var client = new RestClient(this.authUrl); var request = new RestRequest(Method.POST); request.AddHeader("content-type", "application/x-www-form-urlencoded"); request.AddHeader("authorization", "Bearer undefined"); request.AddParameter("application/x-www-form-urlencoded", "grant_type=password&username=" + username + "&password=" + password + "&scope=webApi&client_id=CongreeWebAPI", ParameterType.RequestBody); IRestResponse response = client.Execute(request); AccessToken accessToken = new AccessToken(); accessToken = JsonConvert.DeserializeObject<AccessToken>(response.Content); return accessToken.access_token; } } }
If you are using an empty password the value must be passed as single quotes:
string password = "''";
The listing below shows how to use the class from within any other class:
using System; using System.Collections.Generic; using System.Text; using System.Threading.Tasks; namespace CongreeRestApiTutorial { class CongreeSampleApp { public CongreeSampleApp() { string username = "foo"; string password = "bar"; CongreeHttpClient congreeHttpClient = new CongreeHttpClient("http://localhost"); string token = congreeHttpClient.GetToken(username, password); } } }
Checking content
public CongreeCheckresult Check(string text, string ruleSet) { text = text.Replace("\"", "'"); var client = new RestClient(this.serverUrl + this.documentCheckhUrl + ruleSet); var request = new RestRequest(Method.POST); request.AddHeader("content-type", "application/json"); request.AddHeader("authorization", "Bearer " + this.token); request.AddParameter("application/json", "{\n\t\"Xml\": \"" + text + "\",\n\t\"options\": {\n\t\t\"includeReporting\": true,\n\t\t\"extractTermCandidates\": true,\n\t\t\"includeContextMapping\": false\n\t}\n}", ParameterType.RequestBody); IRestResponse response = client.Execute(request); CongreeCheckresult checkResult = JsonConvert.DeserializeObject<CongreeCheckresult>(response.Content); return checkResult; }
The entire class looks like shown below:
using Newtonsoft.Json; using RestSharp; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Congree { public class CongreeHttpClient { private string authUrl = "/congreeidentityserver/connect/token"; private string documentCheckhUrl = "/congree/api/Linguistic/v1/Check?ruleSet="; private string documentSettingsUrl = "/congree/api/Settings/v1/Document/"; private string serverUrl = ""; private string token = ""; public CongreeHttpClient(string serverUrl, string username, string password) { this.serverUrl = serverUrl; this.token = GetToken(username, password); } public string GetToken(string username, string password) { var client = new RestClient(this.serverUrl + this.authUrl); var request = new RestRequest(Method.POST); request.AddHeader("content-type", "application/x-www-form-urlencoded"); request.AddHeader("authorization", "Bearer undefined"); request.AddParameter("application/x-www-form-urlencoded", "grant_type=password&username=" + username + "&password=" + password + "&scope=webApi&client_id=CongreeWebAPI", ParameterType.RequestBody); IRestResponse response = client.Execute(request); AccessToken accessToken = new AccessToken(); accessToken = JsonConvert.DeserializeObject<AccessToken>(response.Content); this.token = accessToken.access_token; return this.token; } public CongreeCheckresult Check(string text, string ruleSet) { var client = new RestClient(this.serverUrl + this.documentCheckhUrl + ruleSet); var request = new RestRequest(Method.POST); request.AddHeader("content-type", "application/json"); request.AddHeader("authorization", "Bearer " + this.token); CongreeCheckRequest checkRequest = new CongreeCheckRequest(); checkRequest.Xml = text; JsonSerializerSettings settings = new JsonSerializerSettings(); settings.TypeNameHandling = TypeNameHandling.Auto; string serializedRequestJSON = JsonConvert.SerializeObject(checkRequest, settings); request.AddParameter("application/json", serializedRequestJSON, ParameterType.RequestBody); IRestResponse response = client.Execute(request); CongreeCheckresult checkResult = JsonConvert.DeserializeObject<CongreeCheckresult>(response.Content); return checkResult; } public string[] GetDocumentRules() { string[] rules; var client = new RestClient(this.serverUrl + this.documentSettingsUrl); var request = new RestRequest(Method.GET); request.AddHeader("content-type", "application/json"); request.AddHeader("authorization", "Bearer " + this.token); IRestResponse response = client.Execute(request); rules = JsonConvert.DeserializeObject<string[]>(response.Content); return rules; } } }
The code above uses the class CongreeCheckRequest to allow for a creation of a JSON compliant object that is being passed to Congree's REST API
using System; using System.Collections.Generic; using System.Text; namespace Congree { class CongreeCheckRequest { // Input for the linguistic checker.Must be valid XML. public string Xml { get; set; } // Check options public CongreeCheckOptions options { get; set; } public CongreeCheckRequest() { this.options = new CongreeCheckOptions(); } } }
In this class we are using another helper class to configure the different check and response options.
using System; using System.Collections.Generic; using System.Text; namespace Congree { public class CongreeCheckOptions { // Specifies whether valid terms should be included in result public bool includeValidTerms { get; set; } // Specifies whether linguistic report should be generated , public bool includeReporting { get; set; } // Specifies whether context bounds(<?cngr-ctx-b { ContextId}?> ... <? cngr-ctx-e {ContextId}?> blocks) should be included in output XML, public bool includeContextMapping { get; set; } // Specifies whether to perform terminology candidates extraction public bool extractTermCandidates { get; set; } public CongreeCheckOptions() { this.includeValidTerms = true; this.includeReporting = true; this.includeContextMapping = true; this.extractTermCandidates = true; } } }
The Check function uses the token obtain during the authentication. The API returns a JSON object that is being deserialized. The class CongreeCheckresult is shown below.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CongreeProofReader.Congree { public class CongreeCheckresult { public string ResultXml { get; set; } public IList<Error> Errors { get; set; } public Reporting Reporting { get; set; } } public class Error { public string Id { get; set; } public string ContextId { get; set; } public string Type { get; set; } public IList<ErrorDescription> Descriptions { get; set; } public IList<Proposal> Proposals { get; set; } public IList<TermCandidate> TermCandidates { get; set; } public Reporting Reporting { get; set; } } public class ErrorDescription { public string Code { get; set; } public Description Description { get; set; } public IList<ErrorExplanation> Explanation { get; set; } public IList<ErrorExplanationRewrite> ExplanationRewrite { get; set; } } public class Description { public string Header { get; set; } public string Instruction { get; set; } public string Explanation { get; set; } } public class ErrorExplanation { public string Type { get; set; } public string Text { get; set; } } public class ErrorExplanationRewrite { public string Type { get; set; } public string Text { get; set; } } public class Proposal { public string Text { get; set; } public string AdditionalInfo { get; set; } public string BaseTermForm { get; set; } public string ConceptId { get; set; } } public class TermCandidate { public string Id { get; set; } public string Text { get; set; } public string Context { get; set; } public bool IsExists { get; set; } } public class Reporting { public string TotalCheckedWords { get; set; } public string ReleaseLevel { get; set; } public string RelativeReleaseLevel { get; set; } public string SafeReleaseLevel { get; set; } public string SafeReleaseLevelTitle { get; set; } public string AcceptableReleaseLevel { get; set; } public string UnsafeReleaseLevel { get; set; } public string UnsafeReleaseLevelTitle { get; set; } public IList<ReportingByTypes> ReportingByTypes { get; set; } } public class ReportingByTypes { public string Type { get; set; } public string ErrorCount { get; set; } public string Severity { get; set; } public string RelativeSeverity { get; set; } public string Terminology { get; set; } public string Spelling { get; set; } public string Grammar { get; set; } public string Style { get; set; } public string Abbreviation { get; set; } } }
Processing the check result
This section details the response object and the way it is rendered in Congree's UIs. The sample is a part of the infamous Compathy Grasp SX document.
Checking this text results in the following JSON response.
{ "ResultXml": "<body><p><?cngr-ctx-b 1?>Congratulations on your purchase of the <?cngr-lc-b 0?>ContentGrasp SX<?cngr-lc-e 0?> <?cngr-lc-b 1?>headset<?cngr-lc-e 1?>. This revolutionary <?cngr-lc-b 2?>device<?cngr-lc-e 2?> <?cngr-lc-b 3?>will significantly improve<?cngr-lc-e 3?> the quality of your <?cngr-lc-b 4?>technical documentation<?cngr-lc-e 4?> without implementing an additional <?cngr-lc-b 5?>work step<?cngr-lc-e 5?>. During the <?cngr-lc-b 6?>normal review<?cngr-lc-e 6?>, the reviewers or <?cngr-lc-b 7?>test persons<?cngr-lc-e 7?> can <?cngr-lc-b 8?>check<?cngr-lc-e 8?><?cngr-ctx-e 1?></p><ul><li><?cngr-ctx-b 2?><?cngr-lc-b 9?>how<?cngr-lc-e 9?> <?cngr-lc-b 10?>comprehensible individual passages<?cngr-lc-e 10?> were<?cngr-lc-b 11?>;<?cngr-lc-e 11?><?cngr-ctx-e 2?></li><li><?cngr-ctx-b 3?><?cngr-lc-b 12?>how<?cngr-lc-e 12?> carefully <?cngr-lc-b 13?>individual passages<?cngr-lc-e 13?> <?cngr-lc-b 14?>were read<?cngr-lc-e 14?><?cngr-lc-b 15?>;<?cngr-lc-e 15?><?cngr-ctx-e 3?></li><li><?cngr-ctx-b 4?><?cngr-lc-b 16?>which<?cngr-lc-e 16?> passages needed to be read repeatedly.<?cngr-ctx-e 4?></li></ul><p><?cngr-ctx-b 5?>This information <?cngr-lc-b 17?>is recorded<?cngr-lc-e 17?> by the <?cngr-lc-b 18?>headset<?cngr-lc-e 18?> and analyzed by <?cngr-lc-b 19?>intelligent software<?cngr-lc-e 19?> <?cngr-lc-b 20?>using<?cngr-lc-e 20?> a <?cngr-lc-b 21?>sophisticated algorithm<?cngr-lc-e 21?>.<?cngr-ctx-e 5?></p><p><?cngr-ctx-b 6?>The result enables detailed, <?cngr-lc-b 22?>systematic <?cngr-lc-b 23?>improvement<?cngr-lc-e 23?> of the comprehensibility of <?cngr-lc-b 24?>technical document<?cngr-lc-e 22?><?cngr-lc-e 24?> at an <?cngr-lc-b 25?>unprecedented level<?cngr-lc-e 25?>.<?cngr-ctx-e 6?></p></body>", "Errors": [ { "Id": "0", "ContextId": 1, "Type": "Terminology", "Descriptions": [ { "Code": "DEPR", "Description": { "Header": "Review this term.", "Instruction": "Replace with the corresponding preferred term.", "Explanation": "The status of this term in term database is 'deprecated'." }, "Explanation": [], "ExplanationRewrite": [] } ], "Proposals": [ { "Text": "Compathy ContentGrasp SX", "AdditionalInfo": null, "BaseTermForm": "ContentGrasp SX", "ConceptId": 1 } ] }, { "Id": "1", "ContextId": 1, "Type": "ValidTerm", "Descriptions": [], "Proposals": [ { "Text": "headset", "AdditionalInfo": null, "BaseTermForm": "headset", "ConceptId": 10 } ] }, { "Id": "2", "ContextId": 1, "Type": "Terminology", "Descriptions": [ { "Code": "ADM", "Description": { "Header": "Review this term.", "Instruction": "Check whether it is better to use the corresponding preferred term.", "Explanation": "The status of this term in term database is 'admitted'." }, "Explanation": [], "ExplanationRewrite": [] } ], "Proposals": [ { "Text": "instrument", "AdditionalInfo": null, "BaseTermForm": "device", "ConceptId": 7 } ] }, { "Id": "3", "ContextId": 1, "Type": "Style", "Descriptions": [ { "Code": "s752en", "Description": { "Header": "Review the writing style.", "Instruction": "Avoid the future tense. Use the present tense if appropriate.", "Explanation": "The future tense is not appropriate in technical documentation." }, "Explanation": [ { "Type": "Text", "Text": "If you attempt to copy a directory without using this option, you " }, { "Type": "Explanation", "Text": "will receive" }, { "Type": "Text", "Text": " an error message." } ], "ExplanationRewrite": [ { "Type": "Text", "Text": "If you attempt to copy a directory without using this option, you " }, { "Type": "Explanation", "Text": "receive" }, { "Type": "Text", "Text": " an error message." } ] } ], "Proposals": [] }, { "Id": "8", "ContextId": 1, "Type": "Grammar", "Descriptions": [ { "Code": "g523en", "Description": { "Header": "Review punctuation.", "Instruction": "Insert a punctuation mark such as '.', '!', '?', ':' if appropriate.", "Explanation": "Sentences end with a punctuation mark." }, "Explanation": [ { "Type": "Text", "Text": "Sentences have punctuation marks at the " }, { "Type": "Explanation", "Text": "end" } ], "ExplanationRewrite": [ { "Type": "Text", "Text": "Sentences have punctuation marks at the " }, { "Type": "Explanation", "Text": "end." } ] } ], "Proposals": [] }, { "Id": "9", "ContextId": 2, "Type": "Spelling", "Descriptions": [ { "Code": "o43en", "Description": { "Header": "Review the spelling of this word.", "Instruction": "Capitalize the word.", "Explanation": "Words at the beginning of sentences start with a capital letter." }, "Explanation": [], "ExplanationRewrite": [] } ], "Proposals": [ { "Text": "How", "AdditionalInfo": null, "BaseTermForm": null, "ConceptId": 0 } ] }, { "Id": "11", "ContextId": 2, "Type": "Grammar", "Descriptions": [ { "Code": "g523en", "Description": { "Header": "Review punctuation.", "Instruction": "Insert a punctuation mark such as '.', '!', '?', ':' if appropriate.", "Explanation": "Sentences end with a punctuation mark." }, "Explanation": [ { "Type": "Text", "Text": "Sentences have punctuation marks at the " }, { "Type": "Explanation", "Text": "end" } ], "ExplanationRewrite": [ { "Type": "Text", "Text": "Sentences have punctuation marks at the " }, { "Type": "Explanation", "Text": "end." } ] } ], "Proposals": [] }, { "Id": "12", "ContextId": 3, "Type": "Spelling", "Descriptions": [ { "Code": "o43en", "Description": { "Header": "Review the spelling of this word.", "Instruction": "Capitalize the word.", "Explanation": "Words at the beginning of sentences start with a capital letter." }, "Explanation": [], "ExplanationRewrite": [] } ], "Proposals": [ { "Text": "How", "AdditionalInfo": null, "BaseTermForm": null, "ConceptId": 0 } ] }, { "Id": "14", "ContextId": 3, "Type": "Style", "Descriptions": [ { "Code": "s712en", "Description": { "Header": "Review the writing style.", "Instruction": "This construction uses the passive voice. Consider using the active voice.", "Explanation": "The passive voice emphasizes the result and often obscures the initiator of the action. The active voice reinforces a cause/effect relationship between the initiator, the action and the result." }, "Explanation": [ { "Type": "Text", "Text": "After the tap " }, { "Type": "Explanation", "Text": "has been turned off" }, { "Type": "Text", "Text": ", the shaft will move." } ], "ExplanationRewrite": [ { "Type": "Text", "Text": "After " }, { "Type": "Explanation", "Text": "you have turned the tap off" }, { "Type": "Text", "Text": ", the shaft will move." } ] } ], "Proposals": [] }, { "Id": "15", "ContextId": 3, "Type": "Grammar", "Descriptions": [ { "Code": "g523en", "Description": { "Header": "Review punctuation.", "Instruction": "Insert a punctuation mark such as '.', '!', '?', ':' if appropriate.", "Explanation": "Sentences end with a punctuation mark." }, "Explanation": [ { "Type": "Text", "Text": "Sentences have punctuation marks at the " }, { "Type": "Explanation", "Text": "end" } ], "ExplanationRewrite": [ { "Type": "Text", "Text": "Sentences have punctuation marks at the " }, { "Type": "Explanation", "Text": "end." } ] } ], "Proposals": [] }, { "Id": "16", "ContextId": 4, "Type": "Spelling", "Descriptions": [ { "Code": "o43en", "Description": { "Header": "Review the spelling of this word.", "Instruction": "Capitalize the word.", "Explanation": "Words at the beginning of sentences start with a capital letter." }, "Explanation": [], "ExplanationRewrite": [] } ], "Proposals": [ { "Text": "Which", "AdditionalInfo": null, "BaseTermForm": null, "ConceptId": 0 } ] }, { "Id": "17", "ContextId": 5, "Type": "Style", "Descriptions": [ { "Code": "s712en", "Description": { "Header": "Review the writing style.", "Instruction": "This construction uses the passive voice. Consider using the active voice.", "Explanation": "The passive voice emphasizes the result and often obscures the initiator of the action. The active voice reinforces a cause/effect relationship between the initiator, the action and the result." }, "Explanation": [ { "Type": "Text", "Text": "After the tap " }, { "Type": "Explanation", "Text": "has been turned off" }, { "Type": "Text", "Text": ", the shaft will move." } ], "ExplanationRewrite": [ { "Type": "Text", "Text": "After " }, { "Type": "Explanation", "Text": "you have turned the tap off" }, { "Type": "Text", "Text": ", the shaft will move." } ] } ], "Proposals": [] }, { "Id": "18", "ContextId": 5, "Type": "ValidTerm", "Descriptions": [], "Proposals": [ { "Text": "headset", "AdditionalInfo": null, "BaseTermForm": "headset", "ConceptId": 10 } ] }, { "Id": "20", "ContextId": 5, "Type": "Style", "Descriptions": [ { "Code": "s243en", "Description": { "Header": "Check for ambiguous structures and unclear relations.", "Instruction": "Consider rewriting the '-ing'-construction.", "Explanation": "The sentence may be ambiguous. The '-ing'-form can pose a problem for translation." }, "Explanation": [ { "Type": "Text", "Text": "1) " }, { "Type": "Explanation", "Text": "Disabling" }, { "Type": "Text", "Text": " network services prevents IP packets from doing any harm to the system.\\n\\n2) The Document Editor sends an edit message request " }, { "Type": "Explanation", "Text": "using" }, { "Type": "Text", "Text": " the file name as a parameter for the message." } ], "ExplanationRewrite": [ { "Type": "Text", "Text": "1) " }, { "Type": "Explanation", "Text": "The disabling of" }, { "Type": "Text", "Text": " network services prevents IP packets from doing any harm to the system.\\nOR:\\n" }, { "Type": "Explanation", "Text": "If you disable" }, { "Type": "Text", "Text": " the network services, the IP packets do not do any harm to the system.\\n\\n2) The Document Editor sends an edit message request " }, { "Type": "Explanation", "Text": "that uses" }, { "Type": "Text", "Text": " the file name as a parameter for the message.\\nOR:\\nThe Document Editor sends an edit message request " }, { "Type": "Explanation", "Text": "by using" }, { "Type": "Text", "Text": " the file name as a parameter for the message." } ] } ], "Proposals": [] }, { "Id": "22", "ContextId": 6, "Type": "Style", "Descriptions": [ { "Code": "s221en", "Description": { "Header": "Check for ambiguous structures and unclear relations.", "Instruction": "Avoid more than one noun modifier with 'of'. Rephrase the sentence if possible.", "Explanation": "It might be unclear what is modified by the second 'of'-phrase." }, "Explanation": [ { "Type": "Text", "Text": "The " }, { "Type": "Explanation", "Text": "invitation of the members of the committee" }, { "Type": "Text", "Text": " was sent out last Friday." } ], "ExplanationRewrite": [ { "Type": "Explanation", "Text": "The invitation of the committee members" }, { "Type": "Text", "Text": " was sent out last Friday." } ] } ], "Proposals": [] }, { "Id": "23", "ContextId": 6, "Type": "Terminology", "Descriptions": [ { "Code": "POSNEG", "Description": { "Header": "Review this term.", "Instruction": "Check whether in this context the corresponding preferred term is the better choice.", "Explanation": "This is a deprecated term and it is also a preferred or admitted term." }, "Explanation": [], "ExplanationRewrite": [] } ], "Proposals": [ { "Text": "improvement", "AdditionalInfo": null, "BaseTermForm": "improvement", "ConceptId": 11 }, { "Text": "upgrade", "AdditionalInfo": null, "BaseTermForm": "improvement", "ConceptId": 12 } ] } ], "TermCandidates": [ { "Id": "4", "Text": "technical documentation", "Context": "Congratulations on your purchase of the ContentGrasp SX headset. This revolutionary device will significantly improve the quality of your technical documentation without implementing an additional work step. During the normal review, the reviewers or test persons can check", "IsExist": false }, { "Id": "5", "Text": "work step", "Context": "Congratulations on your purchase of the ContentGrasp SX headset. This revolutionary device will significantly improve the quality of your technical documentation without implementing an additional work step. During the normal review, the reviewers or test persons can check", "IsExist": false }, { "Id": "6", "Text": "normal review", "Context": "Congratulations on your purchase of the ContentGrasp SX headset. This revolutionary device will significantly improve the quality of your technical documentation without implementing an additional work step. During the normal review, the reviewers or test persons can check", "IsExist": false }, { "Id": "7", "Text": "test person", "Context": "Congratulations on your purchase of the ContentGrasp SX headset. This revolutionary device will significantly improve the quality of your technical documentation without implementing an additional work step. During the normal review, the reviewers or test persons can check", "IsExist": false }, { "Id": "10", "Text": "comprehensible individual passage", "Context": "how comprehensible individual passages were;", "IsExist": false }, { "Id": "13", "Text": "individual passage", "Context": "how carefully individual passages were read;", "IsExist": false }, { "Id": "19", "Text": "intelligent software", "Context": "This information is recorded by the headset and analyzed by intelligent software using a sophisticated algorithm.", "IsExist": false }, { "Id": "21", "Text": "sophisticated algorithm", "Context": "This information is recorded by the headset and analyzed by intelligent software using a sophisticated algorithm.", "IsExist": false }, { "Id": "24", "Text": "technical document", "Context": "The result enables detailed, systematic improvement of the comprehensibility of technical document at an unprecedented level.", "IsExist": false }, { "Id": "25", "Text": "unprecedented level", "Context": "The result enables detailed, systematic improvement of the comprehensibility of technical document at an unprecedented level.", "IsExist": false } ], "Reporting": { "TotalCheckedWords": 106, "ReleaseLevel": 0, "RelativeReleaseLevel": 0, "SafeReleaseLevel": 95, "SafeReleaseLevelTitle": "Safe", "AcceptableReleaseLevel": 85, "AcceptableReleaseLevelTitle": "Acceptable", "UnsafeReleaseLevel": 0, "UnsafeReleaseLevelTitle": "Unsafe", "ReportingByTypes": [ { "Type": "Abbreviation", "ErrorCount": 0, "Severity": 100, "RelativeSeverity": 120 }, { "Type": "Grammar", "ErrorCount": 3, "Severity": 91.51, "RelativeSeverity": 66.04000000000002 }, { "Type": "Spelling", "ErrorCount": 3, "Severity": 71.7, "RelativeSeverity": 33.741176470588236 }, { "Type": "Style", "ErrorCount": 5, "Severity": 95.28, "RelativeSeverity": 82.24000000000001 }, { "Type": "Terminology", "ErrorCount": 3, "Severity": 5.66, "RelativeSeverity": 2.663529411764706 } ] }, "FailedParagraphsInfo": { "FailedParagraphsAmount": 0 } }
If there are any findings they are returned within the arry of Errors. Each error is being rendered as a separated item in the UI. Let's analyze the first error object in the JSON response.
{ "Id": "0", "ContextId": 1, "Type": "Terminology", "Descriptions": [ { "Code": "DEPR", "Description": { "Header": "Review this term.", "Instruction": "Replace with the corresponding preferred term.", "Explanation": "The status of this term in term database is 'deprecated'." }, "Explanation": [], "ExplanationRewrite": [] } ], "Proposals": [ { "Text": "Compathy ContentGrasp SX", "AdditionalInfo": null, "BaseTermForm": "ContentGrasp SX", "ConceptId": 1 } ] }
The information in the JSON response is being rendered like shown below.
The following example is a more comprehensive one containing additional information explaining the issue and providing hints to rewrite the sentence.
{ "Id": "17", "ContextId": 5, "Type": "Style", "Descriptions": [ { "Code": "s712en", "Description": { "Header": "Review the writing style.", "Instruction": "This construction uses the passive voice. Consider using the active voice.", "Explanation": "The passive voice emphasizes the result and often obscures the initiator of the action. The active voice reinforces a cause/effect relationship between the initiator, the action and the result." }, "Explanation": [ { "Type": "Text", "Text": "After the tap " }, { "Type": "Explanation", "Text": "has been turned off" }, { "Type": "Text", "Text": ", the shaft will move." } ], "ExplanationRewrite": [ { "Type": "Text", "Text": "After " }, { "Type": "Explanation", "Text": "you have turned the tap off" }, { "Type": "Text", "Text": ", the shaft will move." } ] } ], "Proposals": [] }
Below you see the rendered presentation of this JSON object.
Authoring Memory
Storing XML files into the Authoring Memory
public void StoreXml(string host, string filename, string culture, string token){ var client = new RestClient(host + "/Congree/api/AuthoringMemory/v1/ImportXml?lang=" + culture); var request = new RestRequest(Method.POST); request.AddHeader("Content-Type", "multipart/form-data"); request.AddHeader("Authorization", "Bearer " + token); request.AddHeader("Content-Type", "multipart/form-data"); request.AlwaysMultipartFormData = true; request.AddFile("file", filename, ParameterType.RequestBody); IRestResponse response = client.Execute(request); }
Parameter | Description |
---|---|
host | The address of the server hosting Congree Authoring Server |
filename | The name of the file to be imported. The file must be either a valid file, e.g. the referenced DTD must be accessible or a well-formed XML file. |
culture | The code of the language the imported file is written in. |
token | The Bearer token acquired during the authentication. |
Searching for sentences in the Authoring Memory
public void SearchSentence(string host, string ruleSet, string token, string sentence){ var client = new RestClient(host + "/Congree/api/AuthoringMemory/v1/Search"); var request = new RestRequest(Method.POST); request.AddHeader("Content-Type", "application/json"); request.AddHeader("Accept", "application/json"); request.AddHeader("Authorization", "Bearer " + token); request.AddParameter("undefined", "{ \n \"Xml\": \" + sentence + "\",\n \"RuleSetName\": \" + ruleSet + "\" \n }", ParameterType.RequestBody); IRestResponse response = client.Execute(request); }
Parameter | Description |
---|---|
host | The address of the server hosting Congree Authoring Server |
ruleSet | The name of the ruleset the sentence is checked with. |
token | The Bearer token acquired during the authentication. |
sentence | A well-formed XML structure. |
The request returns a JSON object that is described here: