コード例 #1
0
 /// <summary>Serializes an array property.</summary>
 /// <param name="node">an XMPNode</param>
 /// <param name="indent">the current indent level</param>
 /// <exception cref="System.IO.IOException">Forwards the writer exceptions.</exception>
 /// <exception cref="XmpException">If qualifier and element fields are mixed.</exception>
 private void SerializeCompactRdfArrayProp(XmpNode node, int indent)
 {
     // This is an array.
     Write('>');
     WriteNewline();
     EmitRdfArrayTag(node, true, indent + 1);
     if (node.Options.IsArrayAltText)
     {
         XmpNodeUtils.NormalizeLangArray(node);
     }
     SerializeCompactRdfElementProps(node, indent + 2);
     EmitRdfArrayTag(node, false, indent + 1);
 }
コード例 #2
0
        /// <summary>Recursively handles the "value" for a node.</summary>
        /// <remarks>
        /// 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.
        /// <code>
        /// &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;
        /// </code>
        /// </remarks>
        /// <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="System.IO.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)
        {
            var emitEndTag   = true;
            var indentEndTag = true;

            // Determine the XML element name. Open the start tag with the name and
            // attribute qualifiers.
            var elemName = node.Name;

            if (emitAsRdfValue)
            {
                elemName = "rdf:value";
            }
            else if (elemName == XmpConstants.ArrayItemName)
            {
                elemName = XmpConstants.RdfLi;
            }

            WriteIndent(indent);
            Write('<');
            Write(elemName);
            var hasGeneralQualifiers = false;
            var hasRdfResourceQual   = false;

            for (var it = node.IterateQualifier(); it.HasNext();)
            {
                var qualifier = (XmpNode)it.Next();
                if (!RdfAttrQualifier.Contains(qualifier.Name))
                {
                    hasGeneralQualifiers = true;
                }
                else
                {
                    hasRdfResourceQual = qualifier.Name == "rdf:resource";
                    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", XmpErrorCode.BadRdf);
                }

                // Change serialization to canonical format with inner rdf:Description-tag
                // depending on option
                if (useCanonicalRdf)
                {
                    Write(">");
                    WriteNewline();
                    indent++;
                    WriteIndent(indent);
                    Write(RdfStructStart);
                    Write(">");
                }
                else
                {
                    Write(" rdf:parseType=\"Resource\">");
                }

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

                for (var it = node.IterateQualifier(); it.HasNext();)
                {
                    var qualifier = (XmpNode)it.Next();
                    if (!RdfAttrQualifier.Contains(qualifier.Name))
                    {
                        SerializeCanonicalRdfProperty(qualifier, useCanonicalRdf, false, indent + 1);
                    }
                }

                if (useCanonicalRdf)
                {
                    WriteIndent(indent);
                    Write(RdfStructEnd);
                    WriteNewline();
                    indent--;
                }
            }
            else
            {
                // This node has no general qualifiers. Emit using an unqualified form.
                if (!node.Options.IsCompositeProperty)
                {
                    // This is a simple property.
                    if (node.Options.IsUri)
                    {
                        Write(" rdf:resource=\"");
                        AppendNodeValue(node.Value, true);
                        Write("\"/>");
                        WriteNewline();
                        emitEndTag = false;
                    }
                    else if (string.IsNullOrEmpty(node.Value))
                    {
                        Write("/>");
                        WriteNewline();
                        emitEndTag = false;
                    }
                    else
                    {
                        Write('>');
                        AppendNodeValue(node.Value, false);
                        indentEndTag = false;
                    }
                }
                else
                {
                    if (node.Options.IsArray)
                    {
                        // This is an array.
                        Write('>');
                        WriteNewline();
                        EmitRdfArrayTag(node, true, indent + 1);

                        if (node.Options.IsArrayAltText)
                        {
                            XmpNodeUtils.NormalizeLangArray(node);
                        }

                        for (var it1 = node.IterateChildren(); it1.HasNext();)
                        {
                            var child = (XmpNode)it1.Next();
                            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(RdfEmptyStruct);
                            }
                            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(RdfStructStart);
                                Write(">");
                            }
                            else
                            {
                                Write(" rdf:parseType=\"Resource\">");
                            }

                            WriteNewline();
                            for (var it = node.IterateChildren(); it.HasNext();)
                            {
                                var child = (XmpNode)it.Next();
                                SerializeCanonicalRdfProperty(child, useCanonicalRdf, false, indent + 1);
                            }

                            if (useCanonicalRdf)
                            {
                                WriteIndent(indent);
                                Write(RdfStructEnd);
                                WriteNewline();
                                indent--;
                            }
                        }
                    }
                    else
                    {
                        // This is a struct with an rdf:resource attribute, use the
                        // "empty property element" form.
                        for (var it1 = node.IterateChildren(); it1.HasNext();)
                        {
                            var child = (XmpNode)it1.Next();
                            if (!CanBeRdfAttrProp(child))
                            {
                                throw new XmpException("Can't mix rdf:resource and complex fields", XmpErrorCode.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();
            }
        }