/// <summary>The parent is an RDF pseudo-struct containing an rdf:value field.</summary> /// <remarks> /// The parent is an RDF pseudo-struct containing an rdf:value field. Fix the /// XMP data model. The rdf:value node must be the first child, the other /// children are qualifiers. The form, value, and children of the rdf:value /// node are the real ones. The rdf:value node's qualifiers must be added to /// the others. /// </remarks> /// <param name="xmpParent">the parent xmp node</param> /// <exception cref="Com.Adobe.Xmp.XMPException">thown on parsing errors</exception> private static void FixupQualifiedNode(XMPNode xmpParent) { System.Diagnostics.Debug.Assert(xmpParent.GetOptions().IsStruct() && xmpParent.HasChildren()); XMPNode valueNode = xmpParent.GetChild(1); System.Diagnostics.Debug.Assert("rdf:value".Equals(valueNode.GetName())); // Move the qualifiers on the value node to the parent. // Make sure an xml:lang qualifier stays at the front. // Check for duplicate names between the value node's qualifiers and the parent's children. // The parent's children are about to become qualifiers. Check here, between the groups. // Intra-group duplicates are caught by XMPNode#addChild(...). if (valueNode.GetOptions().GetHasLanguage()) { if (xmpParent.GetOptions().GetHasLanguage()) { throw new XMPException("Redundant xml:lang for rdf:value element", XMPErrorConstants.Badxmp); } XMPNode langQual = valueNode.GetQualifier(1); valueNode.RemoveQualifier(langQual); xmpParent.AddQualifier(langQual); } // Start the remaining copy after the xml:lang qualifier. for (int i = 1; i <= valueNode.GetQualifierLength(); i++) { XMPNode qualifier = valueNode.GetQualifier(i); xmpParent.AddQualifier(qualifier); } // Change the parent's other children into qualifiers. // This loop starts at 1, child 0 is the rdf:value node. for (int i_1 = 2; i_1 <= xmpParent.GetChildrenLength(); i_1++) { XMPNode qualifier = xmpParent.GetChild(i_1); xmpParent.AddQualifier(qualifier); } // Move the options and value last, other checks need the parent's original options. // Move the value node's children to be the parent's children. System.Diagnostics.Debug.Assert(xmpParent.GetOptions().IsStruct() || xmpParent.GetHasValueChild()); xmpParent.SetHasValueChild(false); xmpParent.GetOptions().SetStruct(false); xmpParent.GetOptions().MergeWith(valueNode.GetOptions()); xmpParent.SetValue(valueNode.GetValue()); xmpParent.RemoveChildren(); for (Iterator it = valueNode.IterateChildren(); it.HasNext(); ) { XMPNode child = (XMPNode)it.Next(); xmpParent.AddChild(child); } }