/// <summary>Serializes an <code>XMPMeta</code>-object as RDF into a byte buffer.</summary> /// <param name="xmp">a metadata implementation object</param> /// <param name="options"> /// Options to control the serialization (see /// <see cref="iText.Kernel.XMP.Options.SerializeOptions"/> /// ). /// </param> /// <returns>Returns a byte buffer containing the serialized RDF.</returns> public static byte[] SerializeToBuffer(XMPMetaImpl xmp, SerializeOptions options) { MemoryStream output = new MemoryStream(2048); Serialize(xmp, output, options); return(output.ToArray()); }
// EMPTY /// <summary> /// Parses the input source into an XMP metadata object, including /// de-aliasing and normalisation. /// </summary> /// <param name="input"> /// the input can be an <code>InputStream</code>, a <code>String</code> or /// a byte buffer containing the XMP packet. /// </param> /// <param name="options">the parse options</param> /// <returns>Returns the resulting XMP metadata object</returns> /// <exception cref="iText.Kernel.XMP.XMPException">Thrown if parsing or normalisation fails. /// </exception> public static XMPMeta Parse(Object input, ParseOptions options) { ParameterAsserts.AssertNotNull(input); options = options ?? new ParseOptions(); XmlDocument document = ParseXml(input, options); bool xmpmetaRequired = options.GetRequireXMPMeta(); object[] result = new object[3]; result = FindRootNode(document, xmpmetaRequired, result); if (result != null && result[1] == XMP_RDF) { XMPMetaImpl xmp = ParseRdf.Parse((XmlNode)result[0]); xmp.SetPacketHeader((string)result[2]); // Check if the XMP object shall be normalized if (!options.GetOmitNormalization()) { return(XMPNormalizer.Process(xmp, options)); } return(xmp); } // no appropriate root node found, return empty metadata object return(new XMPMetaImpl()); }
/// <summary>Constructor with optionsl initial values.</summary> /// <remarks> /// Constructor with optionsl initial values. If <code>propName</code> is provided, /// <code>schemaNS</code> has also be provided. /// </remarks> /// <param name="xmp">the iterated metadata object.</param> /// <param name="schemaNS">the iteration is reduced to this schema (optional)</param> /// <param name="propPath">the iteration is redurce to this property within the <code>schemaNS</code> /// </param> /// <param name="options"> /// advanced iteration options, see /// <see cref="iText.Kernel.XMP.Options.IteratorOptions"/> /// </param> /// <exception cref="iText.Kernel.XMP.XMPException">If the node defined by the paramters is not existing. /// </exception> public XMPIteratorImpl(XMPMetaImpl xmp, String schemaNS, String propPath, IteratorOptions options) { // make sure that options is defined at least with defaults this.options = options ?? new IteratorOptions(); // the start node of the iteration depending on the schema and property filter XMPNode startNode; string initialPath = null; bool baseSchema = !String.IsNullOrEmpty(schemaNS); bool baseProperty = !String.IsNullOrEmpty(propPath); if (!baseSchema && !baseProperty) { // complete tree will be iterated startNode = xmp.GetRoot(); } else if (baseSchema && baseProperty) { // Schema and property node provided XMPPath path = XMPPathParser.ExpandXPath(schemaNS, propPath); // base path is the prop path without the property leaf XMPPath basePath = new XMPPath(); for (int i = 0; i < path.Size() - 1; i++) { basePath.Add(path.GetSegment(i)); } startNode = XMPNodeUtils.FindNode(xmp.GetRoot(), path, false, null); this.baseNS = schemaNS; initialPath = basePath.ToString(); } else if (baseSchema && !baseProperty) { // Only Schema provided startNode = XMPNodeUtils.FindSchemaNode(xmp.GetRoot(), schemaNS, false); } else // !baseSchema && baseProperty { // No schema but property provided -> error throw new XMPException("Schema namespace URI is required", XMPError.BADSCHEMA); } // create iterator if (startNode != null) { this.nodeIterator = (!this.options.IsJustChildren()) ? new NodeIterator(this, startNode, initialPath, 1) : new NodeIteratorChildren(this, startNode, initialPath); } else { // create null iterator this.nodeIterator = EmptyList.GetEnumerator(); } }
// EMPTY /// <summary>Normalizes a raw parsed XMPMeta-Object</summary> /// <param name="xmp">the raw metadata object</param> /// <param name="options">the parsing options</param> /// <returns>Returns the normalized metadata object</returns> /// <exception cref="iText.Kernel.XMP.XMPException">Collects all severe processing errors. /// </exception> internal static XMPMeta Process(XMPMetaImpl xmp, ParseOptions options) { XMPNode tree = xmp.GetRoot(); TouchUpDataModel(xmp); MoveExplicitAliases(tree, options); TweakOldXMP(tree); DeleteEmptySchemas(tree); return(xmp); }
/// <summary>Visit all schemas to do general fixes and handle special cases.</summary> /// <param name="xmp">the metadata object implementation</param> /// <exception cref="iText.Kernel.XMP.XMPException">Thrown if the normalisation fails. /// </exception> private static void TouchUpDataModel(XMPMetaImpl xmp) { // make sure the DC schema is existing, because it might be needed within the normalization // if not touched it will be removed by removeEmptySchemas XMPNodeUtils.FindSchemaNode(xmp.GetRoot(), XMPConst.NS_DC, true); // Do the special case fixes within each schema. for (IEnumerator it = xmp.GetRoot().IterateChildren(); it.MoveNext();) { XMPNode currSchema = (XMPNode)it.Current; if (XMPConst.NS_DC.Equals(currSchema.GetName())) { NormalizeDCArrays(currSchema); } else { if (XMPConst.NS_EXIF.Equals(currSchema.GetName())) { // Do a special case fix for exif:GPSTimeStamp. FixGPSTimeStamp(currSchema); XMPNode arrayNode = XMPNodeUtils.FindChildNode(currSchema, "exif:UserComment", false ); if (arrayNode != null) { RepairAltText(arrayNode); } } else { if (XMPConst.NS_DM.Equals(currSchema.GetName())) { // Do a special case migration of xmpDM:copyright to // dc:rights['x-default']. XMPNode dmCopyright = XMPNodeUtils.FindChildNode(currSchema, "xmpDM:copyright", false ); if (dmCopyright != null) { MigrateAudioCopyright(xmp, dmCopyright); } } else { if (XMPConst.NS_XMP_RIGHTS.Equals(currSchema.GetName())) { XMPNode arrayNode = XMPNodeUtils.FindChildNode(currSchema, "xmpRights:UsageTerms" , false); if (arrayNode != null) { RepairAltText(arrayNode); } } } } } } }
/// <summary>Static method to serialize the metadata object.</summary> /// <remarks> /// Static method to serialize the metadata object. For each serialisation, a new XMPSerializer /// instance is created, either XMPSerializerRDF or XMPSerializerPlain so thats its possible to /// serialialize the same XMPMeta objects in two threads. /// </remarks> /// <param name="xmp">a metadata implementation object</param> /// <param name="out">the output stream to serialize to</param> /// <param name="options">serialization options, can be <code>null</code> for default. /// </param> public static void Serialize(XMPMetaImpl xmp, Stream output, SerializeOptions options ) { options = options != null ? options : new SerializeOptions(); // sort the internal data model on demand if (options.GetSort()) { xmp.Sort(); } new XMPSerializerRdf().Serialize(xmp, output, options); }
/// <summary>Serializes an <code>XMPMeta</code>-object as RDF into a string.</summary> /// <remarks> /// Serializes an <code>XMPMeta</code>-object as RDF into a string. /// <em>Note:</em> Encoding is forced to UTF-16 when serializing to a /// string to ensure the correctness of "exact packet size". /// </remarks> /// <param name="xmp">a metadata implementation object</param> /// <param name="options"> /// Options to control the serialization (see /// <see cref="iText.Kernel.XMP.Options.SerializeOptions"/> /// ). /// </param> /// <returns>Returns a string containing the serialized RDF.</returns> public static String SerializeToString(XMPMetaImpl xmp, SerializeOptions options) { // forces the encoding to be UTF-16 to get the correct string length options = options ?? new SerializeOptions(); options.SetEncodeUTF16BE(true); MemoryStream output = new MemoryStream(2048); Serialize(xmp, output, options); try { return(new EncodingNoPreamble(IanaEncodings.GetEncodingEncoding(options.GetEncoding())).GetString(output.GetBuffer())); } catch (Exception) { // cannot happen as UTF-8/16LE/BE is required to be implemented in // Java return(GetString(output.GetBuffer())); } }