IterateQualifier() public method

public IterateQualifier ( ) : IEnumerator
return IEnumerator
Ejemplo n.º 1
0
        /// <summary>
        /// Searches for a qualifier selector in a node:
        /// [?qualName="value"] - an element in an array, chosen by a qualifier value.
        /// No implicit nodes are created for qualifier selectors,
        /// except for an alias to an x-default item.
        /// </summary>
        /// <param name="arrayNode"> an array node </param>
        /// <param name="qualName"> the qualifier name </param>
        /// <param name="qualValue"> the qualifier value </param>
        /// <param name="aliasForm"> in case the qual selector results from an alias,
        ///           an x-default node is created if there has not been one. </param>
        /// <returns> Returns the index of th </returns>
        /// <exception cref="XmpException">  </exception>
        private static int LookupQualSelector(XmpNode arrayNode, string qualName, string qualValue, uint aliasForm)
        {
            if (XML_LANG.Equals(qualName))
            {
                qualValue = Utils.NormalizeLangValue(qualValue);
                int index = LookupLanguageItem(arrayNode, qualValue);
                if (index < 0 && (aliasForm & AliasOptions.PROP_ARRAY_ALT_TEXT) > 0)
                {
                    XmpNode langNode = new XmpNode(ARRAY_ITEM_NAME, null);
                    XmpNode xdefault = new XmpNode(XML_LANG, X_DEFAULT, null);
                    langNode.AddQualifier(xdefault);
                    arrayNode.AddChild(1, langNode);
                    return(1);
                }
                return(index);
            }
            for (int index = 1; index < arrayNode.ChildrenLength; index++)
            {
                XmpNode currItem = arrayNode.GetChild(index);

                for (IEnumerator it = currItem.IterateQualifier(); it.MoveNext();)
                {
                    XmpNode qualifier = (XmpNode)it.Current;
                    if (qualifier != null && qualName.Equals(qualifier.Name) && qualValue.Equals(qualifier.Value))
                    {
                        return(index);
                    }
                }
            }
            return(-1);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// The outermost call is special. The names almost certainly differ. The
        /// qualifiers (and hence options) will differ for an alias to the x-default
        /// item of a langAlt array.
        /// </summary>
        /// <param name="aliasNode"> the alias node </param>
        /// <param name="baseNode"> the base node of the alias </param>
        /// <param name="outerCall"> marks the outer call of the recursion </param>
        /// <exception cref="XmpException"> Forwards XMP errors  </exception>
        private static void CompareAliasedSubtrees(XmpNode aliasNode, XmpNode baseNode, bool outerCall)
        {
            if (!aliasNode.Value.Equals(baseNode.Value) || aliasNode.ChildrenLength != baseNode.ChildrenLength)
            {
                throw new XmpException("Mismatch between alias and base nodes", XmpError.BADXMP);
            }

            if (!outerCall &&
                (!aliasNode.Name.Equals(baseNode.Name) || !aliasNode.Options.Equals(baseNode.Options) ||
                 aliasNode.QualifierLength != baseNode.QualifierLength))
            {
                throw new XmpException("Mismatch between alias and base nodes", XmpError.BADXMP);
            }

            for (IEnumerator an = aliasNode.IterateChildren(), bn = baseNode.IterateChildren();
                 an.MoveNext() && bn.MoveNext();)
            {
                XmpNode aliasChild = (XmpNode)an.Current;
                XmpNode baseChild  = (XmpNode)bn.Current;
                CompareAliasedSubtrees(aliasChild, baseChild, false);
            }


            for (IEnumerator an = aliasNode.IterateQualifier(), bn = baseNode.IterateQualifier();
                 an.MoveNext() && bn.MoveNext();)
            {
                XmpNode aliasQual = (XmpNode)an.Current;
                XmpNode baseQual  = (XmpNode)bn.Current;
                CompareAliasedSubtrees(aliasQual, baseQual, false);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Recursively handles the "value" for a node. It does not matter if it is a
        /// top level property, a field of a struct, or an item of an array. The
        /// indent is that for the property element. An xml:lang qualifier is written
        /// as an attribute of the property start tag, not by itself forcing the
        /// qualified property form. The patterns below mostly ignore attribute
        /// qualifiers like xml:lang. Except for the one struct case, attribute
        /// qualifiers don't affect the output form.
        /// 
        /// <blockquote>
        /// 
        /// <pre>
        /// 	&lt;ns:UnqualifiedSimpleProperty&gt;value&lt;/ns:UnqualifiedSimpleProperty&gt;
        /// 
        /// 	&lt;ns:UnqualifiedStructProperty&gt; (If no rdf:resource qualifier)
        /// 		&lt;rdf:Description&gt;
        /// 			... Fields, same forms as top level properties
        /// 		&lt;/rdf:Description&gt;
        /// 	&lt;/ns:UnqualifiedStructProperty&gt;
        /// 
        /// 	&lt;ns:ResourceStructProperty rdf:resource=&quot;URI&quot;
        /// 		... Fields as attributes
        /// 	&gt;
        /// 
        /// 	&lt;ns:UnqualifiedArrayProperty&gt;
        /// 		&lt;rdf:Bag&gt; or Seq or Alt
        /// 			... Array items as rdf:li elements, same forms as top level properties
        /// 		&lt;/rdf:Bag&gt;
        /// 	&lt;/ns:UnqualifiedArrayProperty&gt;
        /// 
        /// 	&lt;ns:QualifiedProperty&gt;
        /// 		&lt;rdf:Description&gt;
        /// 			&lt;rdf:value&gt; ... Property &quot;value&quot; following the unqualified 
        /// 				forms ... &lt;/rdf:value&gt;
        /// 			... Qualifiers looking like named struct fields
        /// 		&lt;/rdf:Description&gt;
        /// 	&lt;/ns:QualifiedProperty&gt;
        /// </pre>
        /// 
        /// </blockquote>
        /// </summary>
        /// <param name="node"> the property node </param>
        /// <param name="emitAsRdfValue"> property shall be rendered as attribute rather than tag </param>
        /// <param name="useCanonicalRdf"> use canonical form with inner description tag or 
        /// 		  the compact form with rdf:ParseType=&quot;resource&quot; attribute. </param>
        /// <param name="indent"> the current indent level </param>
        /// <exception cref="IOException"> Forwards all writer exceptions. </exception>
        /// <exception cref="XmpException"> If &quot;rdf:resource&quot; and general qualifiers are mixed. </exception>
        private void SerializeCanonicalRdfProperty(XmpNode node, bool useCanonicalRdf, bool emitAsRdfValue, int indent) {
            bool emitEndTag = true;
            bool indentEndTag = true;

            // Determine the XML element name. Open the start tag with the name and
            // attribute qualifiers.

            string elemName = node.Name;
            if (emitAsRdfValue) {
                elemName = "rdf:value";
            }
            else if (XmpConst.ARRAY_ITEM_NAME.Equals(elemName)) {
                elemName = "rdf:li";
            }

            WriteIndent(indent);
            Write('<');
            Write(elemName);

            bool hasGeneralQualifiers = false;
            bool hasRdfResourceQual = false;

            for (IEnumerator it = node.IterateQualifier(); it.MoveNext();) {
                XmpNode qualifier = (XmpNode) it.Current;
                if (qualifier != null) {
                    if (!RDF_ATTR_QUALIFIER.Contains(qualifier.Name)) {
                        hasGeneralQualifiers = true;
                    }
                    else {
                        hasRdfResourceQual = "rdf:resource".Equals(qualifier.Name);
                        if (!emitAsRdfValue) {
                            Write(' ');
                            Write(qualifier.Name);
                            Write("=\"");
                            AppendNodeValue(qualifier.Value, true);
                            Write('"');
                        }
                    }
                }
            }

            // Process the property according to the standard patterns.

            if (hasGeneralQualifiers && !emitAsRdfValue) {
                // This node has general, non-attribute, qualifiers. Emit using the
                // qualified property form.
                // ! The value is output by a recursive call ON THE SAME NODE with
                // emitAsRDFValue set.

                if (hasRdfResourceQual) {
                    throw new XmpException("Can't mix rdf:resource and general qualifiers", XmpError.BADRDF);
                }

                // Change serialization to canonical format with inner rdf:Description-tag
                // depending on option
                if (useCanonicalRdf) {
                    Write(">");
                    WriteNewline();

                    indent++;
                    WriteIndent(indent);
                    Write(RDF_STRUCT_START);
                    Write(">");
                }
                else {
                    Write(" rdf:parseType=\"Resource\">");
                }
                WriteNewline();

                SerializeCanonicalRdfProperty(node, useCanonicalRdf, true, indent + 1);

                for (IEnumerator it = node.IterateQualifier(); it.MoveNext();) {
                    XmpNode qualifier = (XmpNode) it.Current;
                    if (qualifier != null && !RDF_ATTR_QUALIFIER.Contains(qualifier.Name)) {
                        SerializeCanonicalRdfProperty(qualifier, useCanonicalRdf, false, indent + 1);
                    }
                }

                if (useCanonicalRdf) {
                    WriteIndent(indent);
                    Write(RDF_STRUCT_END);
                    WriteNewline();
                    indent--;
                }
            }
            else {
                // This node has no general qualifiers. Emit using an unqualified form.

                if (!node.Options.CompositeProperty) {
                    // This is a simple property.

                    if (node.Options.Uri) {
                        Write(" rdf:resource=\"");
                        AppendNodeValue(node.Value, true);
                        Write("\"/>");
                        WriteNewline();
                        emitEndTag = false;
                    }
                    else if (node.Value == null || "".Equals(node.Value)) {
                        Write("/>");
                        WriteNewline();
                        emitEndTag = false;
                    }
                    else {
                        Write('>');
                        AppendNodeValue(node.Value, false);
                        indentEndTag = false;
                    }
                }
                else if (node.Options.Array) {
                    // This is an array.
                    Write('>');
                    WriteNewline();
                    EmitRdfArrayTag(node, true, indent + 1);
                    if (node.Options.ArrayAltText) {
                        XmpNodeUtils.NormalizeLangArray(node);
                    }
                    for (IEnumerator it = node.IterateChildren(); it.MoveNext();) {
                        XmpNode child = (XmpNode) it.Current;
                        SerializeCanonicalRdfProperty(child, useCanonicalRdf, false, indent + 2);
                    }
                    EmitRdfArrayTag(node, false, indent + 1);
                }
                else if (!hasRdfResourceQual) {
                    // This is a "normal" struct, use the rdf:parseType="Resource" form.
                    if (!node.HasChildren()) {
                        // Change serialization to canonical format with inner rdf:Description-tag
                        // if option is set
                        if (useCanonicalRdf) {
                            Write(">");
                            WriteNewline();
                            WriteIndent(indent + 1);
                            Write(RDF_EMPTY_STRUCT);
                        }
                        else {
                            Write(" rdf:parseType=\"Resource\"/>");
                            emitEndTag = false;
                        }
                        WriteNewline();
                    }
                    else {
                        // Change serialization to canonical format with inner rdf:Description-tag
                        // if option is set
                        if (useCanonicalRdf) {
                            Write(">");
                            WriteNewline();
                            indent++;
                            WriteIndent(indent);
                            Write(RDF_STRUCT_START);
                            Write(">");
                        }
                        else {
                            Write(" rdf:parseType=\"Resource\">");
                        }
                        WriteNewline();

                        for (IEnumerator it = node.IterateChildren(); it.MoveNext();) {
                            XmpNode child = (XmpNode) it.Current;
                            SerializeCanonicalRdfProperty(child, useCanonicalRdf, false, indent + 1);
                        }

                        if (useCanonicalRdf) {
                            WriteIndent(indent);
                            Write(RDF_STRUCT_END);
                            WriteNewline();
                            indent--;
                        }
                    }
                }
                else {
                    // This is a struct with an rdf:resource attribute, use the
                    // "empty property element" form.
                    for (IEnumerator it = node.IterateChildren(); it.MoveNext();) {
                        XmpNode child = (XmpNode) it.Current;
                        if (child != null) {
                            if (!canBeRDFAttrProp(child)) {
                                throw new XmpException("Can't mix rdf:resource and complex fields",
                                                       XmpError.BADRDF);
                            }
                            WriteNewline();
                            WriteIndent(indent + 1);
                            Write(' ');
                            Write(child.Name);
                            Write("=\"");
                            AppendNodeValue(child.Value, true);
                            Write('"');
                        }
                    }
                    Write("/>");
                    WriteNewline();
                    emitEndTag = false;
                }
            }

            // Emit the property element end tag.
            if (emitEndTag) {
                if (indentEndTag) {
                    WriteIndent(indent);
                }
                Write("</");
                Write(elemName);
                Write('>');
                WriteNewline();
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Writes all used namespaces of the subtree in node to the output. 
        /// The subtree is recursivly traversed. </summary>
        /// <param name="node"> the root node of the subtree </param>
        /// <param name="usedPrefixes"> a set containing currently used prefixes </param>
        /// <param name="indent"> the current indent level </param>
        /// <exception cref="IOException"> Forwards all writer exceptions. </exception>
        private void DeclareUsedNamespaces(XmpNode node, ISet usedPrefixes, int indent) {
            if (node.Options.SchemaNode) {
                // The schema node name is the URI, the value is the prefix.
                string prefix = node.Value.Substring(0, node.Value.Length - 1);
                DeclareNamespace(prefix, node.Name, usedPrefixes, indent);
            }
            else if (node.Options.Struct) {
                for (IEnumerator it = node.IterateChildren(); it.MoveNext();) {
                    XmpNode field = (XmpNode) it.Current;
                    if (field == null)
                        continue;
                    DeclareNamespace(field.Name, null, usedPrefixes, indent);
                }
            }

            for (IEnumerator it = node.IterateChildren(); it.MoveNext();) {
                XmpNode child = (XmpNode) it.Current;
                if (child == null)
                    continue;
                DeclareUsedNamespaces(child, usedPrefixes, indent);
            }

            for (IEnumerator it = node.IterateQualifier(); it.MoveNext();) {
                XmpNode qualifier = (XmpNode) it.Current;
                if (qualifier == null)
                    continue;
                DeclareNamespace(qualifier.Name, null, usedPrefixes, indent);
                DeclareUsedNamespaces(qualifier, usedPrefixes, indent);
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Serializes the general qualifier. </summary>
        /// <param name="node"> the root node of the subtree </param>
        /// <param name="indent"> the current indent level </param>
        /// <exception cref="IOException"> Forwards all writer exceptions. </exception>
        /// <exception cref="XmpException"> If qualifier and element fields are mixed. </exception>
        private void SerializeCompactRdfGeneralQualifier(int indent, XmpNode node) {
            // The node has general qualifiers, ones that can't be
            // attributes on a property element.
            // Emit using the qualified property pseudo-struct form. The
            // value is output by a call
            // to SerializePrettyRDFProperty with emitAsRDFValue set.
            Write(" rdf:parseType=\"Resource\">");
            WriteNewline();

            SerializeCanonicalRdfProperty(node, false, true, indent + 1);

            for (IEnumerator iq = node.IterateQualifier(); iq.MoveNext();) {
                XmpNode qualifier = (XmpNode) iq.Current;
                if (qualifier == null)
                    continue;
                SerializeCanonicalRdfProperty(qualifier, false, false, indent + 1);
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// The outermost call is special. The names almost certainly differ. The
        /// qualifiers (and hence options) will differ for an alias to the x-default
        /// item of a langAlt array.
        /// </summary>
        /// <param name="aliasNode"> the alias node </param>
        /// <param name="baseNode"> the base node of the alias </param>
        /// <param name="outerCall"> marks the outer call of the recursion </param>
        /// <exception cref="XmpException"> Forwards XMP errors  </exception>
        private static void CompareAliasedSubtrees(XmpNode aliasNode, XmpNode baseNode, bool outerCall) {
            if (!aliasNode.Value.Equals(baseNode.Value) || aliasNode.ChildrenLength != baseNode.ChildrenLength) {
                throw new XmpException("Mismatch between alias and base nodes", XmpError.BADXMP);
            }

            if (!outerCall &&
                (!aliasNode.Name.Equals(baseNode.Name) || !aliasNode.Options.Equals(baseNode.Options) ||
                 aliasNode.QualifierLength != baseNode.QualifierLength)) {
                throw new XmpException("Mismatch between alias and base nodes", XmpError.BADXMP);
            }

            for (IEnumerator an = aliasNode.IterateChildren(), bn = baseNode.IterateChildren();
                 an.MoveNext() && bn.MoveNext();) {
                XmpNode aliasChild = (XmpNode) an.Current;
                XmpNode baseChild = (XmpNode) bn.Current;
                CompareAliasedSubtrees(aliasChild, baseChild, false);
            }


            for (IEnumerator an = aliasNode.IterateQualifier(), bn = baseNode.IterateQualifier();
                 an.MoveNext() && bn.MoveNext();) {
                XmpNode aliasQual = (XmpNode) an.Current;
                XmpNode baseQual = (XmpNode) bn.Current;
                CompareAliasedSubtrees(aliasQual, baseQual, false);
            }
        }