예제 #1
0
        /// <summary>
        /// Given the specified element in a given namespace, remaps it into a
        /// <paramref name="targetNamespace"/> and trims elements and attributes that
        /// don't conform to the schema.
        /// </summary>
        /// <param name="element">Element to fit.</param>
        /// <param name="schemaNamespace">Namespace of element.</param>
        /// <param name="targetNamespace">Target namespace.</param>
        /// <returns>A new <see cref="XElement"/> that fits the specified <paramref name="targetNamespace"/>.</returns>
        private static XElement FitElementToSchema(XElement element, string schemaNamespace, string targetNamespace)
        {
            Debug.Assert(element != null, "element != null");
            Debug.Assert(schemaNamespace != null, "schemaNamespace != null");
            Debug.Assert(targetNamespace != null, "targetNamespace != null");
            Debug.Assert(
                targetNamespace == XmlConstants.EdmV1dot1Namespace,
                "targetNamespace == XmlConstants.EdmV1dot1Namespace -- otherwise update CreateTargetSchemaSet to pull other schemas");

            XmlSchemaSet schemas = CreateTargetSchemaSet();
            XElement     result  = UpdateNamespaces(element, schemaNamespace, targetNamespace);

            XNodeSchemaApplier.Apply(schemas, result);
            return(result);
        }
예제 #2
0
        /// <summary>
        /// Updates the namespaces under the specified <paramref name="element"/>, changing <paramref name="oldNamespaceName"/>
        /// into <paramref name="newNamespaceName"/>.
        /// </summary>
        /// <param name="element">Element to update (recursively).</param>
        /// <param name="oldNamespaceName">Old namespace.</param>
        /// <param name="newNamespaceName">New namespace.</param>
        /// <returns>The updated element.</returns>
        /// <remarks>
        /// Currently, the updates are in-place, so the returned element is always <paramref name="element"/>.
        ///
        /// For valid cases, there will be no qualified CSDL attributes, so those code paths are
        /// not likely to hit - however the code preserves the namespaces so it can fail
        /// correctly later on.
        /// </remarks>
        private static XElement UpdateNamespaces(XElement element, string oldNamespaceName, string newNamespaceName)
        {
            Debug.Assert(element != null, "element != null");
            Debug.Assert(oldNamespaceName != null, "oldNamespaceName != null");
            Debug.Assert(newNamespaceName != null, "newNamespaceName != null");

            XNamespace oldNamespace = XNamespace.Get(oldNamespaceName);
            XNamespace newNamespace = XNamespace.Get(newNamespaceName);

            Stack <XElement> pending = new Stack <XElement>();

            pending.Push(element);
            do
            {
                XElement e = pending.Pop();
                if (e.Name.Namespace == oldNamespace)
                {
                    e.Name = newNamespace.GetName(e.Name.LocalName);
                }

                List <XAttribute> attributesToReplace = null;
                foreach (XAttribute attribute in e.Attributes())
                {
                    if (attribute.IsNamespaceDeclaration)
                    {
                        if (attribute.Value == oldNamespaceName)
                        {
                            attribute.Value = newNamespaceName;
                        }
                    }
                    else if (attribute.Name.Namespace == oldNamespace || IsOpenTypeAttribute(attribute))
                    {
                        XNodeSchemaApplier.AppendWithCreation(ref attributesToReplace, attribute);
                    }
                }

                if (attributesToReplace != null)
                {
                    attributesToReplace.Remove();
                    foreach (XAttribute attribute in attributesToReplace)
                    {
                        if (IsOpenTypeAttribute(attribute))
                        {
                            XAttribute existingAttribute = e.Attributes().SingleOrDefault(a => a.Name.NamespaceName == XmlConstants.EdmV1dot2Namespace && a.Name.LocalName == attribute.Name.LocalName);

                            if (existingAttribute == null)
                            {
                                e.Add(new XAttribute(XNamespace.Get(XmlConstants.EdmV1dot2Namespace) + attribute.Name.LocalName, attribute.Value));
                            }
                            else
                            {
                                existingAttribute.Value = attribute.Value;
                            }
                        }
                        else
                        {
                            e.Add(new XAttribute(newNamespace.GetName(attribute.Name.LocalName), attribute.Value));
                        }
                    }
                }

                foreach (var child in e.Elements())
                {
                    pending.Push(child);
                }
            }while (pending.Count > 0);

            return(element);
        }