/// <summary> /// /// </summary> /// <param name="idCda"></param> /// <param name="cdaVersion"></param> /// <param name="cdaXml"></param> /// <param name="otherQueries"></param> /// <param name="rootPath"></param> /// <param name="queryName"></param> /// <param name="queryReturnType"></param> /// <param name="entityCodeWithPrefix"></param> /// <returns></returns> public static async Task<FromXmlTransformationsResult> FromXmlTransformations( int idCda, int cdaVersion, XNode cdaXml, string rootPath, string queryName, IList<XElement> otherQueries = null, QueryReturnTypes queryReturnType = QueryReturnTypes.XPathBoolean | QueryReturnTypes.XPathInt | QueryReturnTypes.XQueryFlwrInt, bool entityCodeWithPrefix = true ) { if (cdaXml == null) { throw new ArgumentNullException(nameof(cdaXml)); } if (string.IsNullOrWhiteSpace(rootPath)) { throw new ArgumentNullException(nameof(rootPath)); } if (string.IsNullOrWhiteSpace(queryName)) { throw new ArgumentNullException(nameof(queryName)); } Dictionary<QueryReturnTypes, string> queryContainers = new Dictionary<QueryReturnTypes, string>() { { QueryReturnTypes.XPathBoolean, @"boolean(/" + rootPath + "[{0}])" }, { QueryReturnTypes.XPathInt, @"count(/" + rootPath + "[{0}])" }, { QueryReturnTypes.XQueryFlwrInt, @"for $x in /" + rootPath + " let $where := ({0}) return if ($where) then 1 else 0" }, }; XDocument QueryTransformations = new XDocument(new XElement("QUERIES")); List<Rule> rules = new List<Rule>(); List<CdaTag> cdaTags = new List<CdaTag>(); List<QueryReturnTypes> returnTypes = new List<QueryReturnTypes>(); Condition conditionObj = null; Operator operatorObj = null; bool tryGet = false; XElement conditionsRoot = ((XElement)cdaXml).FirstNode as XElement; var cdaBuilderXPath = new StringBuilder(); var cdaBuilderXQuery = new StringBuilder(); char openGroupChar = '('; char closeGroupChar = ')'; if (queryReturnType.HasFlag(QueryReturnTypes.XPathBoolean)) returnTypes.Add(QueryReturnTypes.XPathBoolean); if (queryReturnType.HasFlag(QueryReturnTypes.XPathInt)) returnTypes.Add(QueryReturnTypes.XPathInt); if (queryReturnType.HasFlag(QueryReturnTypes.XQueryFlwrInt)) returnTypes.Add(QueryReturnTypes.XQueryFlwrInt); foreach (var group in conditionsRoot.Descendants("GROUP")) { var conditionSymbol = group.Attribute("CONDITION").Value; cdaBuilderXPath.AppendFormat(@"{0}", openGroupChar); cdaBuilderXQuery.AppendFormat(@"{0}", openGroupChar); foreach (var ruleElement in group.Elements("RULE")) { var entityCode = ruleElement.Attribute("ENTITYCODE").Value; var entityType = ruleElement.Attribute("ENTITYTYPE").Value; var operatorSymbol = ruleElement.Attribute("OPERATOR").Value; var value = ruleElement.Attribute("VALUE").Value; Rule rule = new Rule { EntityCode = entityCode, Operator = operatorSymbol, Value = value, EntityType = entityCode.Substring(0, 3), GroupCondition = conditionSymbol }; var cdaTag = await CreateCdaTags(rule); rules.Add(rule); cdaTags.Add(cdaTag); if (entityCodeWithPrefix) { entityCode = AddPrefixToEntityCode(rule); } cdaBuilderXPath.AppendFormat(XPathEntityPrefix, entityCode); cdaBuilderXQuery.AppendFormat(XQueryEntityPrefix, entityCode); tryGet = Operators.ListKeyValue.TryGetValue(operatorSymbol.ToLower(), out operatorObj); if (tryGet) { cdaBuilderXPath.AppendFormat(@" {0}", string.Format(operatorObj.XPathValue, value)); cdaBuilderXQuery.AppendFormat(@" {0}", string.Format(operatorObj.XPathValue, value)); } tryGet = Conditions.ListKeyValue.TryGetValue(conditionSymbol.ToLower(), out conditionObj); if (tryGet) { cdaBuilderXPath.AppendFormat(@" {0} ", conditionObj.Value); cdaBuilderXQuery.AppendFormat(@" {0} ", conditionObj.Value); } } cdaBuilderXPath.RemoveLast($" {conditionObj.Value} "); cdaBuilderXQuery.RemoveLast($" {conditionObj.Value} "); cdaBuilderXPath.AppendFormat(@"{0}", closeGroupChar); cdaBuilderXQuery.AppendFormat(@"{0}", closeGroupChar); tryGet = Conditions.ListKeyValue.TryGetValue(conditionSymbol.ToLower(), out conditionObj); if (tryGet) { cdaBuilderXPath.AppendFormat(@" {0} ", conditionObj.Value); cdaBuilderXQuery.AppendFormat(@" {0} ", conditionObj.Value); } } cdaBuilderXPath.RemoveLast($" {conditionObj.Value} "); cdaBuilderXQuery.RemoveLast($" {conditionObj.Value} "); var internalCode = await CreateCdaInternalCode(rules); if (otherQueries?.Count > 0) { QueryTransformations.Element("QUERIES").Add(otherQueries); } var cdaBuilderXPathEscaped = cdaBuilderXPath.ToString().EscapeString(); var cdaBuilderXQueryEscaped = cdaBuilderXPath.ToString().EscapeString(); returnTypes.ForEach(type => { var queryElement = new XElement("QUERY", new XAttribute("NAME", queryName)); switch (type) { case QueryReturnTypes.XPathInt: queryElement.Add( new XAttribute("TYPE", "xpath"), new XAttribute("EXPRESSIONTYPE", string.Empty), new XAttribute("RETURNTYPE", "int"), new XAttribute("WHERECLAUSE", string.Format(queryContainers[QueryReturnTypes.XPathInt], cdaBuilderXPathEscaped)), new XAttribute("IDCDA", idCda), new XAttribute("CDAVERSION", cdaVersion) ); break; case QueryReturnTypes.XPathBoolean: queryElement.Add( new XAttribute("TYPE", "xpath"), new XAttribute("EXPRESSIONTYPE", string.Empty), new XAttribute("RETURNTYPE", "bool"), new XAttribute("WHERECLAUSE", string.Format(queryContainers[QueryReturnTypes.XPathBoolean], cdaBuilderXPathEscaped)), new XAttribute("IDCDA", idCda), new XAttribute("CDAVERSION", cdaVersion) ); break; case QueryReturnTypes.XQueryFlwrInt: queryElement.Add( new XAttribute("TYPE", "xquery"), new XAttribute("EXPRESSIONTYPE", "flwr"), new XAttribute("RETURNTYPE", "int"), new XAttribute("WHERECLAUSE", string.Format(queryContainers[QueryReturnTypes.XQueryFlwrInt], cdaBuilderXQueryEscaped)), new XAttribute("IDCDA", idCda), new XAttribute("CDAVERSION", cdaVersion) ); break; default: break; } QueryTransformations.Root.Add(queryElement); }); FromXmlTransformationsResult result = new FromXmlTransformationsResult() { QueryTransformations = new QueryTransformation() { ResultValue = QueryTransformations, Success = true }, TagsTransformation = new TagsTransformation() { ResultValue = cdaTags, Success = true }, InternalCode = new InternalCode() { ResultValue = internalCode, Success = true } }; return await Task.FromResult(result); }
private static async Task<CdaTag> CreateCdaTags(Rule rule) { var cdaTag = new CdaTag { EntityCode = rule.EntityCode.ToLower(), Operator = rule.Operator.ToLower(), Value = rule.Value.ToLower() }; cdaTag.TagText = cdaTag.ToString(); return await Task.FromResult(cdaTag); }
private static string AddPrefixToEntityCode(Rule rule) { return $"{rule.EntityType.Substring(0, 1)}-{rule.EntityCode}"; }
/// <summary> /// /// </summary> /// <param name="cdaXml"></param> /// <returns></returns> public static async Task<IList<CdaTag>> CreateCdaTags(XNode cdaXml) { List<CdaTag> cdaTags = new List<CdaTag>(); XElement conditionsRoot = ((XElement)cdaXml).FirstNode as XElement; foreach (var group in conditionsRoot.Descendants("GROUP")) { var conditionSymbol = group.Attribute("CONDITION").Value; foreach (var ruleElement in group.Elements("RULE")) { var entityCode = ruleElement.Attribute("ENTITYCODE").Value; var entityType = ruleElement.Attribute("ENTITYTYPE").Value; var operatorSymbol = ruleElement.Attribute("OPERATOR").Value; var value = ruleElement.Attribute("VALUE").Value; Rule rule = new Rule { EntityCode = entityCode, Operator = operatorSymbol, Value = value, EntityType = string.IsNullOrWhiteSpace(entityType) ? entityCode.Substring(0, 3) : entityType, GroupCondition = conditionSymbol }; var cdaTag = await CreateCdaTags(rule); cdaTags.Add(cdaTag); } } return await Task.FromResult(cdaTags); }