private static void ProcessReference(MappingSet set, Reference reference) { // Figure out what type of reference it is, process each type differently. if (Cardinality.IsOneToMany(reference.Cardinality1, reference.Cardinality2)) { ProcessOneToManyReference(set, reference); } else if (Cardinality.IsOneToOne(reference.Cardinality1, reference.Cardinality2)) { ProcessOneToOneReference(set, reference); } else if (Cardinality.IsManyToMany(reference.Cardinality1, reference.Cardinality2)) { ProcessManyToManyReference(set, reference); } }
private void BuildCardinalityAndConformance(StringBuilder sb) { if (_cardinality != null) { string op = "="; if (_cardinality.Right != Cardinality.MANY) { var rhs = _cardinality.Right; if ((_cardinality.Left == 0) && (!_cardinality.IsZeroToZero())) { op = " < "; rhs++; //right-hand side (rhs) needs to be increment b/c we are doing a "less than", e.g. less than 2 is 0 and 1, however _cardinality.Right will be 1 } else if (_cardinality.IsZeroToZero()) { op = "="; rhs = 0; } if ((_attribute != null) && (_attribute.GetNumberOfValuesDefined() <= 1)) //1 to 1, or 0 to 1, on an attribute, just give the name, no need for count. if an attribute has more than one value then it'll be prepended with current() { //cardinality on attribute could only be 0..0, 0..1, or 1..1 if (_cardinality.Right == 1) { if (_cardinality.Left == 0) //0..1 { if (_attribute != null && _hasOptionalParentContext) { if ((_conformance == Conformance.SHOULD) || (_conformance == Conformance.MAY)) { sb.AppendFormat("not({0}{1}{2}{3}{4}) or {0}{1}{2}{3}{4}", Sentinels.CONTEXT_TOKEN, Sentinels.ELEMENT_TOKEN, Sentinels.ATTRIBUTE_TOKEN, Sentinels.CHILDELEMENT_TOKEN, Sentinels.VALUESET_TOKEN); } else { sb.AppendFormat("{0}{1}{2}{3}{4}", Sentinels.CONTEXT_TOKEN, Sentinels.ELEMENT_TOKEN, Sentinels.ATTRIBUTE_TOKEN, Sentinels.CHILDELEMENT_TOKEN, Sentinels.VALUESET_TOKEN); } } else { sb.AppendFormat("not({0}{1}{5}) or {0}{1}{2}{3}{4}", Sentinels.CONTEXT_TOKEN, Sentinels.ELEMENT_TOKEN, Sentinels.ATTRIBUTE_TOKEN, Sentinels.CHILDELEMENT_TOKEN, Sentinels.VALUESET_TOKEN, Sentinels.ATTRIBUTE_IMMUTABLE_TOKEN); } } else //1..1 { sb.AppendFormat("{0}{1}{2}{3}{4}", Sentinels.CONTEXT_TOKEN, Sentinels.ELEMENT_TOKEN, Sentinels.ATTRIBUTE_TOKEN, Sentinels.CHILDELEMENT_TOKEN, Sentinels.VALUESET_TOKEN); } } else if (_cardinality.IsZeroToZero()) //0..0 { sb.AppendFormat("not({0}{1}{2}{3}{4})", Sentinels.CONTEXT_TOKEN, Sentinels.ELEMENT_TOKEN, Sentinels.ATTRIBUTE_TOKEN, Sentinels.CHILDELEMENT_TOKEN, Sentinels.VALUESET_TOKEN); } else //unexpected cardinality, but database could have it as a bad value so output valid xpath { sb.AppendFormat("{0}{1}{2}{3}{4}", Sentinels.CONTEXT_TOKEN, Sentinels.ELEMENT_TOKEN, Sentinels.ATTRIBUTE_TOKEN, Sentinels.CHILDELEMENT_TOKEN, Sentinels.VALUESET_TOKEN); } } else { if (_cardinality.IsOneToOne() || (_cardinality.Left == 0)) { if (_outputPathOnly) { sb.AppendFormat("{0}{1}{2}{3}{4}", Sentinels.CONTEXT_TOKEN, Sentinels.ELEMENT_TOKEN, Sentinels.ATTRIBUTE_TOKEN, Sentinels.CHILDELEMENT_TOKEN, Sentinels.VALUESET_TOKEN); } else { sb.AppendFormat("count({0}{1}{2}{3}{4}){5}{6}", Sentinels.CONTEXT_TOKEN, Sentinels.ELEMENT_TOKEN, Sentinels.ATTRIBUTE_TOKEN, Sentinels.CHILDELEMENT_TOKEN, Sentinels.VALUESET_TOKEN, op, rhs); } } else { if (_outputPathOnly) { sb.AppendFormat("{0}{1}{2}{3}{4}", Sentinels.CONTEXT_TOKEN, Sentinels.ELEMENT_TOKEN, Sentinels.ATTRIBUTE_TOKEN, Sentinels.CHILDELEMENT_TOKEN, Sentinels.VALUESET_TOKEN); } else { sb.AppendFormat("count({0}{1}{2}{3}{4})[. >= {5}] <= {6}", Sentinels.CONTEXT_TOKEN, Sentinels.ELEMENT_TOKEN, Sentinels.ATTRIBUTE_TOKEN, Sentinels.CHILDELEMENT_TOKEN, Sentinels.VALUESET_TOKEN, _cardinality.Left, _cardinality.Right); } } } } else { if (_cardinality.IsZeroToMany()) { if (_isBranchRoot) { sb.AppendFormat("not({0}{1}{2}{3}{4}) or {0}{1}{2}{3}{4}", Sentinels.CONTEXT_TOKEN, Sentinels.ELEMENT_TOKEN, Sentinels.ATTRIBUTE_TOKEN, Sentinels.VALUESET_TOKEN, Sentinels.CHILDELEMENT_TOKEN); } else { sb.AppendFormat("not({0}{1}) or {0}{1}{2}{3}{4}", Sentinels.CONTEXT_TOKEN, Sentinels.ELEMENT_TOKEN, Sentinels.ATTRIBUTE_TOKEN, Sentinels.VALUESET_TOKEN, Sentinels.CHILDELEMENT_TOKEN); } } else { if (_cardinality.IsOneToMany()) { if (_outputPathOnly) { sb.AppendFormat("{0}{1}{2}{3}{4}", Sentinels.CONTEXT_TOKEN, Sentinels.ELEMENT_TOKEN, Sentinels.ATTRIBUTE_TOKEN, Sentinels.CHILDELEMENT_TOKEN, Sentinels.VALUESET_TOKEN); } else { sb.AppendFormat("count({0}{1}{2}{3}{4}) > 0", Sentinels.CONTEXT_TOKEN, Sentinels.ELEMENT_TOKEN, Sentinels.ATTRIBUTE_TOKEN, Sentinels.CHILDELEMENT_TOKEN, Sentinels.VALUESET_TOKEN); } } else { if (_outputPathOnly) { sb.AppendFormat("{0}{1}{2}{3}{4}", Sentinels.CONTEXT_TOKEN, Sentinels.ELEMENT_TOKEN, Sentinels.ATTRIBUTE_TOKEN, Sentinels.CHILDELEMENT_TOKEN, Sentinels.VALUESET_TOKEN); } else { sb.AppendFormat("count({0}{1}{2}{3}{4}){5}", Sentinels.CONTEXT_TOKEN, Sentinels.ELEMENT_TOKEN, Sentinels.ATTRIBUTE_TOKEN, Sentinels.CHILDELEMENT_TOKEN, Sentinels.VALUESET_TOKEN, op); } } } } if (((_conformance == Conformance.SHALL_NOT) || (_conformance == Conformance.SHOULD_NOT) || (_conformance == Conformance.MAY_NOT)) && (!_cardinality.IsZeroToMany()) && (!_cardinality.IsZeroToZero())) { sb.Insert(0, "not("); sb.Append(")"); } } }