public override INodePointer CreateChild(SifXPathContext context, string name, int i)
        {
            SifVersion   version    = Version;
            IElementDef  subEleDef  = GetChildDef(name);
            SifFormatter formatter  = Adk.Dtd.GetFormatter(version);
            SifElement   sifElement = (SifElement)fElement;

            // Check to see if this child has a render surrogate defined
            IRenderSurrogate rs = subEleDef.GetVersionInfo(version).GetSurrogate();

            if (rs != null)
            {
                return(rs.CreateChild(this, formatter, version, context));
            }

            if (subEleDef.Field)
            {
                SifSimpleType ssf = subEleDef.TypeConverter.GetSifSimpleType(null);
                SimpleField   sf  = formatter.SetField(sifElement, subEleDef, ssf, version);
                return(SimpleFieldPointer.Create(this, sf));
            }
            else
            {
                SifElement newEle = SifElement.Create(sifElement, subEleDef);
                formatter.AddChild(sifElement, newEle, version);
                return(new SifElementPointer(this, newEle, version));
            }
        }
Beispiel #2
0
        /// <summary>
        /// Creates a child element, if supported by this node
        /// </summary>
        /// <param name="parentPointer"></param>
        /// <param name="formatter"></param>
        /// <param name="version"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public INodePointer CreateChild(INodePointer parentPointer, SifFormatter formatter, SifVersion version,
                                        SifXPathContext context)
        {
            // 1) Create an instance of the SimpleField with a null value (It's assigned later)

            //
            // STEP 2
            // Find the actual field to set the value to
            //
            SifElement parent        = (SifElement)((SifElementPointer)parentPointer).Element;
            SifElement targetElement = parent;

            if (!fElementDef.Field)
            {
                //	This indicates a child SifElement that needs to be created
                targetElement = SifElement.Create(parent, fElementDef);

                formatter.AddChild(parent, targetElement, version);
            }

            IElementDef fieldDef = null;

            if (fValueXpath.Equals("."))
            {
                fieldDef = fElementDef;
            }
            else
            {
                String fieldName = fValueXpath;
                if (fValueXpath.StartsWith("@"))
                {
                    fieldName = fValueXpath.Substring(1);
                }
                fieldDef = Adk.Dtd.LookupElementDef(fElementDef, fieldName);
            }


            if (fieldDef == null)
            {
                throw new ArgumentException("Support for value path {" + fValueXpath +
                                            "} is not supported by XPathSurrogate.");
            }

            SifSimpleType ssf = fieldDef.TypeConverter.GetSifSimpleType(null);
            SimpleField   sf  = ssf.CreateField(targetElement, fieldDef);

            targetElement.SetField(sf);


            // 2) built out a fake set of node pointers representing the SIF 1.5r1 path and
            //    return the root pointer from that stack
            return(BuildLegacyPointers(parentPointer, sf));
        }
        /// <summary>
        /// Creates a child element, if supported by this node
        /// </summary>
        /// <param name="parentPointer"></param>
        /// <param name="formatter"></param>
        /// <param name="version"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public INodePointer CreateChild( INodePointer parentPointer, SifFormatter formatter, SifVersion version,
                                         SifXPathContext context )
        {
            // 1) Create an instance of the SimpleField with a null value (It's assigned later)

            //
            // STEP 2
            // Find the actual field to set the value to
            //
            SifElement parent = (SifElement) ((SifElementPointer) parentPointer).Element;
            SifElement targetElement = parent;

            if ( !fElementDef.Field )
            {
                //	This indicates a child SifElement that needs to be created
                targetElement = SifElement.Create( parent, fElementDef );

                formatter.AddChild( parent, targetElement, version );
            }

            IElementDef fieldDef = null;
            if ( fValueXpath.Equals( "." ) )
            {
                fieldDef = fElementDef;
            }
            else
            {
                String fieldName = fValueXpath;
                if ( fValueXpath.StartsWith( "@" ) )
                {
                    fieldName = fValueXpath.Substring( 1 );
                }
                fieldDef = Adk.Dtd.LookupElementDef( fElementDef, fieldName );
            }

            if ( fieldDef == null )
            {
                throw new ArgumentException( "Support for value path {" + fValueXpath +
                                             "} is not supported by XPathSurrogate." );
            }

            SifSimpleType ssf = fieldDef.TypeConverter.GetSifSimpleType( null );
            SimpleField sf = ssf.CreateField( targetElement, fieldDef );
            targetElement.SetField( sf );

            // 2) built out a fake set of node pointers representing the SIF 1.5r1 path and
            //    return the root pointer from that stack
            return BuildLegacyPointers( parentPointer, sf );
        }
        /// <summary>
        /// Creates a child element and sets the text value
        /// </summary>
        /// <param name="relativeTo">The parent SIFElement to add the new element to</param>
        /// <param name="tag">The tag name of the element</param>
        /// <param name="valueBuilder">The ValueBuilder instance to use to evaluate macros</param>
        /// <param name="version">The version of SIF for which this mapping operation is being evaluated</param>
        /// <param name="textFormatter">The SIFFormatter instance used to parse strings into strongly-typed data values.
        /// For many uses of this API, this formatter is equivalent to Adk.TextFormatter</param>
        /// <param name="pathFormatter">The SIFFormatter instance used for setting child SIFElements on their parents.
        /// This formatter may be different than the text formatter. The text formatter is, for
        /// compatibility's sake defaulted to SIF 1.x. However, the path formatter must be 
        /// correct for the mappings path being evaluated.</param>
        /// <returns></returns>
        private SifElement _createChild(
            SifElement relativeTo,
            String tag,
            IValueBuilder valueBuilder,
            SifVersion version,
            SifFormatter textFormatter,
            SifFormatter pathFormatter)
        {
            string _tag = tag;
            string assignValue = null;
            int eq = tag.IndexOf('=');
            if (eq != -1)
            {
                _tag = tag.Substring(0, (eq) - (0));
                string str = tag.Substring(eq + 1);
                assignValue = valueBuilder == null ? str : valueBuilder.Evaluate(str);
            }

            //  Lookup the IElementDef
            IElementDef def = Adk.Dtd.LookupElementDef(relativeTo.ElementDef, _tag);
            if (def == null)
            {
                def = Adk.Dtd.LookupElementDef(_tag);
            }
            if (def == null)
            {
                throw new AdkSchemaException(_tag + " is not a recognized element or attribute of " + relativeTo.Tag);
            }

            try
            {
                TypeConverter defConverter = def.TypeConverter;
                if (defConverter == null)
                {
                    defConverter = SifTypeConverters.STRING;
                }
                if (def.Field)
                {
                    SimpleField field = defConverter.ParseField(relativeTo, def, textFormatter, assignValue);
                    relativeTo.SetField(field);
                }
                else
                {
                    //  Create element instance

                    SifElement ele = (SifElement)ClassFactory.CreateInstance(def.FQClassName);
                    ele.ElementDef = def;
                    pathFormatter.AddChild(relativeTo, ele, version);
                    if (assignValue != null)
                    {
                        // TODO: THis needs to be done using the type converter
                        ele.TextValue = assignValue;
                    }

                    return ele;
                }
            }
            catch (TypeLoadException tle)
            {
                throw new SystemException(
                    "The " + def.Package +
                    " Sdo module is not loaded (ensure the Adk is initialized to load this module)", tle);
            }
            catch (Exception thr)
            {
                throw new SystemException(
                    "Failed to create an instance of the " + def.ClassName + " class from the " + def.Package +
                    " Sdo module: ", thr);
            }

            return null;
        }
        /// <summary>  Recursively builds elements and attributes relative to a SifElement.</summary>
        /// <param name="relativeTo">The SifElement this iteration is relative to. For the
        /// first call to this method, the <i>relativeTo</i> parameter is usually
        /// a SifDataObject such as StudentPersonal to which the XPath query
        /// string is relative. With each subsequent call it is the SifElement
        /// or SimpleField that was previously processed.</param>
        /// <param name="path">A running path of the segments processed thus far; an empty
        /// StringBuffer should be passed to this parameter the first time the
        /// method is called </param>
        /// <param name="curSegment">The current segment of the path that is being processed.
        /// For the first call to this method, the <i>curSegment</i> should be
        /// the portion of the XPath query string up to the first forward slash,
        /// exclusive.</param>
        /// <param name="nextSegment">The remaining portion of the path to be processed.
        /// For the first call to this method, the <i>nextSegment</i> should be
        /// the portion of the XPath query string following the first forward
        /// slash.</param>
        /// <param name="prevAttributes">An optional array of attribute values that were
        /// used to construct an Element in the processing of the last segment.
        /// The array is comprised of attribute name and value pairs such that
        /// element N is an attribute name and N+1 is its value. For the first
        /// call to this method, the array should be null. For subsequent calls,
        /// it should be null unless an Element was constructed from attribute
        /// values.</param>
        /// <param name="version">The version of SIF for which this mapping operation is being evaluated</param>
        /// <param name="textFormatter">The SIFFormatter instance used to parse strings into strongly-typed data values.
        /// For many uses of this API, this formatter is equivalent to ADK.TextFormatter</param>
        /// <param name="pathFormatter">The SIFFormatter instance used for setting child SIFElements on their parents.
        /// This formatter may be different than the text formatter. The text formatter is, for
        /// compatibility's sake defaulted to SIF 1.x. However, the path formatter must be 
        /// correct for the mappings path being evaluated.</param>
        /// <param name="valueBuilder"></param>
        /// <returns> The Element satisfying the query, or <c>null</c> if no
        /// match was found (unless the <i>create</i> parameter is true). If the
        /// query resolves to an attribute, a SimpleField object is returned. If
        /// it resolves to an element, a SifElement object is returned. In both
        /// cases the caller can obtain the text value of the attribute or
        /// element by calling its <c>TextValue</c> Property.
        /// </returns>
        private Element _xpathBuild(
            SifElement relativeTo,
            StringBuilder path,
            string curSegment,
            string nextSegment,
            string[] prevAttributes,
            IValueBuilder valueBuilder,
            SifVersion version,
            SifFormatter textFormatter,
            SifFormatter pathFormatter)
        {
            string[] _prevAttributes = null;
            SifElement nextEle = null;

            int asgnEq = curSegment.LastIndexOf('=');
            int attr = curSegment.LastIndexOf('@', asgnEq == -1 ? curSegment.Length - 1 : asgnEq - 1);
            int bracket = curSegment.IndexOf('[');
            if (bracket != -1)
            {
                if (attr == -1)
                {
                    throw new AdkSchemaException("Invalid query: \"" + curSegment +
                                                  "\" must be in the form [@Attr='value1','value2',...]");
                }

                string subEleTag = curSegment.Substring(0, (bracket) - (0));

                int lastBracket = curSegment.LastIndexOf(']');
                string[] attrList = curSegment.Substring(bracket + 1, (lastBracket) - (bracket + 1)).Split(',');
                _prevAttributes = new string[attrList.Length * 2];
                int _prevI = 0;

                for (int a = 0; a < attrList.Length; a++)
                {
                    string _curSegment = attrList[a];

                    //  Determine the value of the attribute
                    int eq = _curSegment.IndexOf("=");
                    string val = _curSegment.Substring(eq + 1);
                    string v = null;
                    if (val[0] == '\'')
                    {
                        int end = val.IndexOf('\'', 1);
                        if (end != -1)
                        {
                            v = valueBuilder == null
                                    ? val.Substring(1, (end) - (1))
                                    : valueBuilder.Evaluate(val.Substring(1, (end) - (1)));
                        }
                    }

                    if (v == null)
                    {
                        throw new AdkSchemaException("Attribute value (" + val +
                                                      ") must be in the form @Attribute='value'");
                    }

                    string attrName = _curSegment.Substring(1, (eq) - (1));

                    _prevAttributes[_prevI++] = attrName;
                    _prevAttributes[_prevI++] = v;

                    if (nextEle == null)
                    {
                        //
                        //  Look at all of the peer elements to determine if any have the
                        //  attribute value set. If so, return it; otherwise create a new
                        //  instance of the element with the attribute set. For example, if
                        //  curSegment is "Address[@Type='M']", we must look at all of the
                        //  Address children of relativeTo in order to determine if any
                        //  currently exist with a Type field set to a value of 'M'. If one
                        //  does, then it already exists and there is nothing to do; if
                        //  not found, however, a new Address child must be added with a
                        //  Type field of 'M'.
                        //

                        //  Lookup the IElementDef of relativeTo
                        IElementDef subEleDef = Adk.Dtd.LookupElementDef(relativeTo.ElementDef, subEleTag);
                        if (subEleDef == null)
                        {
                            subEleDef = Adk.Dtd.LookupElementDef(subEleTag);
                            if (subEleDef == null)
                            {
                                throw new AdkSchemaException(subEleTag + " is not a recognized attribute of " +
                                                              relativeTo.Tag);
                            }
                        }

                        bool repeatable = subEleDef.IsRepeatable(relativeTo.SifVersion);

                        SifElementList peers = relativeTo.GetChildList(subEleDef);

                        if (curSegment.IndexOf("+]") == -1)
                        {
                            //
                            //  Determine if relatSifElementListiveTo has any children that already
                            //  define this attribute/value; if not, create a new instance.
                            //  If subEleDef is not repeatable, however, we cannot add
                            //  another instance of it regardless.
                            //
                            for (int i = 0; i < peers.Count && nextEle == null; i++)
                            {
                                SimpleField ftest = peers[i].GetField(attrName);
                                if (ftest != null && ftest.TextValue.Equals(v))
                                {
                                    nextEle = peers[i];
                                }
                            }
                        }

                        if (nextEle == null)
                        {
                            if (!(peers.Count > 0 && !repeatable))
                            {
                                nextEle =
                                    _createChild(relativeTo, subEleTag, valueBuilder, version, textFormatter,
                                                  pathFormatter);
                            }
                            else
                            {
                                //
                                //  subEleDef is not repeatable, so we need to back up
                                //  and add this attribute/value to a fresh instance of
                                //  relativeTo if possible. First use _xpath(path) to try
                                //  to select that instance in case it already exists (otherwise
                                //  we'd create a new instance each iteration, which is
                                //  not the desired result.)
                                //

                                string _tmp;
                                if (path.Length > 0)
                                {
                                    _tmp = path + "/" + curSegment;
                                }
                                else
                                {
                                    _tmp = curSegment;
                                }
                                if (XPATH_DEBUG)
                                {
                                    Console.Out.Write("Searching for path relative to " +
                                                       relativeTo.Root.ElementDef.Name + ": " + _tmp);
                                }

                                int _del = _tmp.IndexOf('/');
                                nextEle =
                                    (SifElement)
                                    _xpath((SifElement)relativeTo.Root,
                                            _tmp.Substring(0, (_del == -1 ? _tmp.Length : _del) - (0)),
                                            _del == -1 ? null : _tmp.Substring(_del + 1));

                                if (XPATH_DEBUG)
                                {
                                    if (nextEle == null)
                                    {
                                        Console.Out.WriteLine("; not found, a new instance will be created");
                                    }
                                    else
                                    {
                                        Console.Out.WriteLine("; found");
                                    }
                                }

                                if (nextEle == null)
                                {
                                    if (relativeTo.ElementDef.IsRepeatable(relativeTo.SifVersion))
                                    {
                                        //  Clone relativeTo
                                        SifElement grandParent = (SifElement)relativeTo.Parent;
                                        nextEle = SifElement.Create(grandParent, relativeTo.ElementDef);
                                        pathFormatter.AddChild(grandParent, nextEle, version);

                                        //  Clone subEleDef; this now becomes nextEle
                                        SifElement newEle = SifElement.Create(nextEle, subEleDef);
                                        pathFormatter.AddChild(nextEle, newEle, version);
                                        _copyAttributes(nextEle, prevAttributes);
                                        nextEle = newEle;
                                    }
                                    else
                                    {
                                        throw new AdkSchemaException(
                                            "It is not possible to create the element or attribute identified by this path: " +
                                            _tmp + (nextSegment == null ? "" : "/" + nextSegment) +
                                            ". The element or attribute is either undefined in this version of SIF, " +
                                            "or an attempt is being made to create another instance of an element that is not Repeatable.");
                                    }
                                }
                            }
                        }
                    }

                    if (nextEle != null)
                    {
                        _createField(nextEle, attrName, v);
                    }

                    if (a == attrList.Length && nextEle == null)
                    {
                        return null;
                    }
                }
            }
            else
            {
                //  Search for the named attribute/element
                if (attr != -1)
                {
                    SimpleField ff = relativeTo.GetField(curSegment.Substring(1));
                    if (ff == null)
                    {
                        ff = _createField(relativeTo, curSegment.Substring(1), null);
                    }

                    return ff;
                }
                else
                {
                    string _tag = curSegment;
                    int eq = curSegment.IndexOf('=');
                    if (eq != -1)
                    {
                        _tag = curSegment.Substring(0, (eq) - (0));
                    }

                    nextEle = relativeTo.GetChild(_tag);
                    if (nextEle == null)
                    {
                        //  The curSegment element does not exist as a child of the relativeTo
                        //  object, so create it.
                        nextEle =
                            _createChild(relativeTo, curSegment, valueBuilder, version, textFormatter, pathFormatter);
                        if (nextEle == null)
                        {
                            if (nextSegment == null)
                            {
                                return relativeTo.GetField(_tag);
                            }
                            return null;
                        }
                    }
                }
            }

            //  Continue the search if nextSegment has a value
            if (nextEle != null && (nextSegment != null && nextSegment.Length > 0))
            {
                int i = nextSegment.IndexOf('/');

                if (path.Length > 0)
                {
                    path.Append("/");
                }
                path.Append(curSegment);

                return _xpathBuild(
                    nextEle,
                    path, i == -1 ? nextSegment : nextSegment.Substring(0, (i)),
                    i == -1 ? null : nextSegment.Substring(i + 1),
                    _prevAttributes,
                    valueBuilder,
                    version,
                    textFormatter,
                    pathFormatter);
            }

            if (nextSegment == null && nextEle != null && (nextEle.TextValue == null || nextEle.TextValue.Length == 0))
            {
                int eq2 = curSegment.LastIndexOf('=');
                if (eq2 != -1)
                {
                    if (bracket == -1 || (curSegment.LastIndexOf(']') < eq2))
                    {
                        //
                        //  An equals sign in the final segment indicates there is
                        //  a value constant or expression following the XPath
                        //  (e.g. "OtherId[@Type='06']=@pad($(PERMNUM),0,5)" ). Use
                        //  the user-supplied ValueBuilder to evaluate it.
                        //
                        string str = curSegment.Substring(eq2 + 1);
                        nextEle.TextValue = valueBuilder == null ? str : valueBuilder.Evaluate(str);
                    }
                }
            }

            return nextEle;
        }
        public bool ReadRaw(
            XmlReader reader,
            SifVersion version,
            SifElement parent,
            SifFormatter formatter )
        {
            String value = null;
            //
            // STEP 1
            // Determine if this surrogate can handle the parsing of this node.
            // Retrieve the node value as a string
            //

            String[] xPathParts = fLegacyXpath.Split( '/' );
            XmlNodeType eventType = reader.NodeType;
            String localName = reader.LocalName;
            if ( eventType == XmlNodeType.Element &&
                 localName.Equals( xPathParts[0] ) )
            {
                try
                {
                    int currentSegment = 0;
                    int lastSegment = xPathParts.Length - 1;
                    if ( xPathParts[lastSegment].StartsWith( "@" ) )
                    {
                        lastSegment--;
                    }
                    while ( currentSegment < lastSegment )
                    {
                        reader.Read();
                        currentSegment++;

                        if ( !reader.LocalName.Equals( xPathParts[currentSegment] ) )
                        {
                            ThrowParseException
                                ( "Element {" + reader.LocalName +
                                  "} is not supported by XPathSurrogate path " + fLegacyXpath,
                                  version );
                        }
                    }

                    // New we are at the last segment in the XPath, and the XMLStreamReader
                    // should be positioned on the proper node. The last segment is either
                    // an attribute or an element, which need to be read differently
                    String finalSegment = xPathParts[xPathParts.Length - 1];
                    if ( finalSegment.StartsWith( "@" ) )
                    {
                        value = reader.GetAttribute( finalSegment.Substring( 1 ) );
                    }
                    else
                    {
                        value = ReadElementTextValue( reader );
                    }

                    // Note: Unlike the Java ADK, Surrogates in the the .NET ADK do not have to worry about
                    // completely consuming the XMLElement and advancing to the next tag. The .NET
                    // Surrogates are handed a reader that only allows reading the current node and
                    // the parent reader is automatically advanced when the surrogate is done.
                }
                catch ( Exception xse )
                {
                    ThrowParseException( xse, reader.LocalName, version );
                }
            }
            else
            {
                // No match was found
                return false;
            }

            //
            // STEP 2
            // Find the actual field to set the value to
            //
            IElementDef fieldDef;
            SifElement targetElement = parent;
            if ( fValueXpath.Equals( "." ) && fElementDef.Field )
            {
                fieldDef = fElementDef;
            }
            else
            {
                //	This indicates a child SifElement that needs to be created
                try
                {
                    targetElement = SifElement.Create( parent, fElementDef );
                }
                catch ( AdkSchemaException adkse )
                {
                    ThrowParseException( adkse, reader.LocalName, version );
                }

                formatter.AddChild( parent, targetElement, version );

                if ( fValueXpath.Equals( "." ) )
                {
                    fieldDef = fElementDef;
                }
                else
                {
                    String fieldName = fValueXpath;
                    if ( fValueXpath.StartsWith( "@" ) )
                    {
                        fieldName = fValueXpath.Substring( 1 );
                    }
                    fieldDef = Adk.Dtd.LookupElementDef( fElementDef, fieldName );
                }
            }

            if ( fieldDef == null )
            {
                throw new InvalidOperationException
                    ( "Support for value path {" + fValueXpath +
                      "} is not supported by XPathSurrogate." );
            }

            //
            // STEP 3
            // Set the value to the field
            //
            TypeConverter converter = fieldDef.TypeConverter;
            if ( converter == null )
            {
                // TODO: Determine if we should be automatically creating a converter
                // for elementDefs that don't have one, or whether we should just throw the
                // spurious data away.
                converter = SifTypeConverters.STRING;
            }
            SifSimpleType data = converter.Parse( formatter, value );
            targetElement.SetField( fieldDef, data );

            return true;
        }
Beispiel #7
0
        public bool ReadRaw(
            XmlReader reader,
            SifVersion version,
            SifElement parent,
            SifFormatter formatter)
        {
            String value = null;

            //
            // STEP 1
            // Determine if this surrogate can handle the parsing of this node.
            // Retrieve the node value as a string
            //

            String[]    xPathParts = fLegacyXpath.Split('/');
            XmlNodeType eventType  = reader.NodeType;
            String      localName  = reader.LocalName;

            if (eventType == XmlNodeType.Element &&
                localName.Equals(xPathParts[0]))
            {
                try
                {
                    int currentSegment = 0;
                    int lastSegment    = xPathParts.Length - 1;
                    if (xPathParts[lastSegment].StartsWith("@"))
                    {
                        lastSegment--;
                    }
                    while (currentSegment < lastSegment)
                    {
                        reader.Read();
                        currentSegment++;

                        if (!reader.LocalName.Equals(xPathParts[currentSegment]))
                        {
                            ThrowParseException
                                ("Element {" + reader.LocalName +
                                "} is not supported by XPathSurrogate path " + fLegacyXpath,
                                version);
                        }
                    }

                    // New we are at the last segment in the XPath, and the XMLStreamReader
                    // should be positioned on the proper node. The last segment is either
                    // an attribute or an element, which need to be read differently
                    String finalSegment = xPathParts[xPathParts.Length - 1];
                    if (finalSegment.StartsWith("@"))
                    {
                        value = reader.GetAttribute(finalSegment.Substring(1));
                    }
                    else
                    {
                        value = ReadElementTextValue(reader);
                    }

                    // Note: Unlike the Java ADK, Surrogates in the the .NET ADK do not have to worry about
                    // completely consuming the XMLElement and advancing to the next tag. The .NET
                    // Surrogates are handed a reader that only allows reading the current node and
                    // the parent reader is automatically advanced when the surrogate is done.
                }
                catch (Exception xse)
                {
                    ThrowParseException(xse, reader.LocalName, version);
                }
            }
            else
            {
                // No match was found
                return(false);
            }

            //
            // STEP 2
            // Find the actual field to set the value to
            //
            IElementDef fieldDef;
            SifElement  targetElement = parent;

            if (fValueXpath.Equals(".") && fElementDef.Field)
            {
                fieldDef = fElementDef;
            }
            else
            {
                //	This indicates a child SifElement that needs to be created
                try
                {
                    targetElement = SifElement.Create(parent, fElementDef);
                }
                catch (AdkSchemaException adkse)
                {
                    ThrowParseException(adkse, reader.LocalName, version);
                }

                formatter.AddChild(parent, targetElement, version);

                if (fValueXpath.Equals("."))
                {
                    fieldDef = fElementDef;
                }
                else
                {
                    String fieldName = fValueXpath;
                    if (fValueXpath.StartsWith("@"))
                    {
                        fieldName = fValueXpath.Substring(1);
                    }
                    fieldDef = Adk.Dtd.LookupElementDef(fElementDef, fieldName);
                }
            }

            if (fieldDef == null)
            {
                throw new InvalidOperationException
                          ("Support for value path {" + fValueXpath +
                          "} is not supported by XPathSurrogate.");
            }


            //
            // STEP 3
            // Set the value to the field
            //
            TypeConverter converter = fieldDef.TypeConverter;

            if (converter == null)
            {
                // TODO: Determine if we should be automatically creating a converter
                // for elementDefs that don't have one, or whether we should just throw the
                // spurious data away.
                converter = SifTypeConverters.STRING;
            }
            SifSimpleType data = converter.Parse(formatter, value);

            targetElement.SetField(fieldDef, data);

            return(true);
        }