示例#1
0
        /// <summary>
        /// Creates the attribute nodes for the current element and resolves attribute prefixes.
        /// </summary>
        /// <returns>An array containing the created attributes.</returns>
        /// <param name="elementName">The name of the element.</param>
        private ASXML[] _resolveAttributes(ASQName elementName)
        {
            if (m_unresolvedAttrs.length == 0)
            {
                return(Array.Empty <ASXML>());
            }

            ASXML[] resolvedAttrs = new ASXML[m_unresolvedAttrs.length];

            for (int i = 0, n = m_unresolvedAttrs.length; i < n; i++)
            {
                string?prefix = m_unresolvedAttrs[i].prefix;

                ASNamespace?attributeNamespace = (prefix == null) ? ASNamespace.@public : _resolvePrefix(prefix);

                if (attributeNamespace == null)
                {
                    throw _error(
                              ErrorCode.XML_PREFIX_NOT_BOUND,
                              prefix,
                              m_unresolvedAttrs[i].localName,
                              line: m_unresolvedAttrs[i].lineNumber
                              );
                }

                ASQName attributeName = new ASQName(attributeNamespace, m_unresolvedAttrs[i].localName);

                // Check for duplicate attributes
                for (int j = 0; j < i; j++)
                {
                    if (ASQName.AS_equals(attributeName, resolvedAttrs[j].name()))
                    {
                        throw _error(
                                  ErrorCode.XML_ATTRIBUTE_DUPLICATE,
                                  attributeName.AS_toString(),
                                  elementName.AS_toString(),
                                  line: m_unresolvedAttrs[i].lineNumber
                                  );
                    }
                }

                resolvedAttrs[i] = ASXML.unsafeCreateAttribute(attributeName, m_unresolvedAttrs[i].value);
            }

            m_unresolvedAttrs.clear();
            return(resolvedAttrs);
        }
示例#2
0
        /// <summary>
        /// Checks if the given <see cref="ASQName"/> is a valid node name for an element, attribute
        /// or processing instruction. If it is not valid, attempts to create a valid name by removing
        /// the namespace prefix from the name, or by substituting a default namespace URI if the
        /// name has a null namespace URI.
        /// </summary>
        ///
        /// <param name="name">The <see cref="ASQName"/> instance to check.</param>
        /// <param name="nodeType">Must be one of <see cref="XMLNodeType.ELEMENT"/>, <see cref="XMLNodeType.ATTRIBUTE"/>
        /// or <see cref="XMLNodeType.PROCESSING_INSTRUCTION"/>.</param>
        /// <param name="defaultNS">The default namespace to use if the namespace URI of <paramref name="name"/>
        /// is null. If this is null, the value of <see cref="ASNamespace.getDefault()"/> is used if
        /// <paramref name="nodeType"/> if <see cref="XMLNodeType.ELEMENT"/>, and <see cref="ASNamespace.@public"/>
        /// otherwise.</param>
        ///
        /// <returns>If <paramref name="name"/> is a valid name for a node of the given type, returns
        /// <paramref name="name"/>; if a new valid name could be created by removing the namespace prefix
        /// and/or by substituting a default namespace URI, returns the new name; otherwise, returns null.</returns>
        public static ASQName?tryMakeValidNodeName(ASQName?name, XMLNodeType nodeType, ASNamespace?defaultNS = null)
        {
            if (name == null || !isValidName(name.localName))
            {
                return(null);
            }

            switch (nodeType)
            {
            case XMLNodeType.ELEMENT:
                if (name.uri == null)
                {
                    return(new ASQName(defaultNS ?? ASNamespace.getDefault(), name.localName));
                }
                break;

            case XMLNodeType.PROCESSING_INSTRUCTION:
                if (name.uri == null || name.uri.Length != 0)
                {
                    return(new ASQName(ASNamespace.@public, name.localName));
                }
                break;

            case XMLNodeType.ATTRIBUTE: {
                if (name.uri == null)
                {
                    name = new ASQName(defaultNS ?? ASNamespace.@public, name.localName);
                }
                else if (name.prefix != null &&
                         ((name.prefix.Length == 0 && name.uri.Length != 0) || name.prefix == "xmlns"))
                {
                    name = ASQName.unsafeCreate(prefix: null, name.uri, name.localName);
                }

                if (name.uri !.Length == 0 && name.localName == "xmlns")
                {
                    return(null);
                }

                break;
            }
            }

            return(name);
        }
示例#3
0
        private void _enterElement(ASXML elem)
        {
            _writeIndent();

            ASQName elemName  = elem.internalGetName() !;
            var     stackItem = new TagStackItem {
                tempPrefixIdStart = m_nextTempPrefixId,
                nsDeclBeginIndex  = m_nsInScope.length,
                localName         = elemName.localName,
                prefix            = _getPrefix(elemName, isAttr: false)
            };

            elem.internalGetNamespaceDecls(ref m_nsInScope);

            m_parts.add("<");
            _writeName(stackItem.prefix, stackItem.localName);

            foreach (ASXML attr in elem.getAttributeEnumerator())
            {
                ASQName attrName  = attr.internalGetName() !;
                string  attrValue = attr.nodeText !;

                m_parts.add(" ");
                _writeName(_getPrefix(attrName, isAttr: true), attrName.localName);
                m_parts.add("=\"");
                m_parts.add(XMLHelper.escape(attrValue, 0, attrValue.Length, ref m_escBuffer, isAttr: true));
                m_parts.add("\"");
            }

            // If this is the root we must include the ancestor namespaces as well.
            int nsDeclStart = (m_tagStack.length == 0) ? 0 : stackItem.nsDeclBeginIndex;

            for (int i = nsDeclStart, n = m_nsInScope.length; i < n; i++)
            {
                ASNamespace nsDecl = m_nsInScope[i];

                if (nsDecl.prefix !.Length != 0)
                {
                    m_parts.add(" xmlns:");
                    m_parts.add(nsDecl.prefix);
                    m_parts.add("=\"");
                }