/// <summary> /// Parses the root node of an XMP Path, checks if namespace and prefix fit together /// and resolve the property to the base property if it is an alias. /// </summary> /// <param name="schemaNS">the root namespace</param> /// <param name="pos">the parsing position helper</param> /// <param name="expandedXPath">the path to contribute to</param> /// <exception cref="iText.Kernel.XMP.XMPException">If the path is not valid.</exception> private static void ParseRootNode(String schemaNS, PathPosition pos, XMPPath expandedXPath) { while (pos.stepEnd < pos.path.Length && "/[*".IndexOf(pos.path[pos.stepEnd]) < 0) { pos.stepEnd++; } if (pos.stepEnd == pos.stepBegin) { throw new XMPException("Empty initial XMPPath step", XMPError.BADXPATH); } String rootProp = VerifyXPathRoot(schemaNS, pos.path.JSubstring(pos.stepBegin, pos.stepEnd)); XMPAliasInfo aliasInfo = XMPMetaFactory.GetSchemaRegistry().FindAlias(rootProp); if (aliasInfo == null) { // add schema xpath step expandedXPath.Add(new XMPPathSegment(schemaNS, XMPPath.SCHEMA_NODE)); XMPPathSegment rootStep = new XMPPathSegment(rootProp, XMPPath.STRUCT_FIELD_STEP); expandedXPath.Add(rootStep); } else { // add schema xpath step and base step of alias expandedXPath.Add(new XMPPathSegment(aliasInfo.GetNamespace(), XMPPath.SCHEMA_NODE)); XMPPathSegment rootStep = new XMPPathSegment(VerifyXPathRoot(aliasInfo.GetNamespace(), aliasInfo.GetPropName ()), XMPPath.STRUCT_FIELD_STEP); rootStep.SetAlias(true); rootStep.SetAliasForm(aliasInfo.GetAliasForm().GetOptions()); expandedXPath.Add(rootStep); if (aliasInfo.GetAliasForm().IsArrayAltText()) { XMPPathSegment qualSelectorStep = new XMPPathSegment("[?xml:lang='x-default']", XMPPath.QUAL_SELECTOR_STEP ); qualSelectorStep.SetAlias(true); qualSelectorStep.SetAliasForm(aliasInfo.GetAliasForm().GetOptions()); expandedXPath.Add(qualSelectorStep); } else { if (aliasInfo.GetAliasForm().IsArray()) { XMPPathSegment indexStep = new XMPPathSegment("[1]", XMPPath.ARRAY_INDEX_STEP); indexStep.SetAlias(true); indexStep.SetAliasForm(aliasInfo.GetAliasForm().GetOptions()); expandedXPath.Add(indexStep); } } } }
/// <summary> /// Parses the root node of an XMP Path, checks if namespace and prefix fit together /// and resolve the property to the base property if it is an alias. /// </summary> /// <param name="schemaNS">the root namespace</param> /// <param name="pos">the parsing position helper</param> /// <param name="expandedXPath">the path to contribute to</param> /// <exception cref="Com.Adobe.Xmp.XMPException">If the path is not valid.</exception> private static void ParseRootNode(string schemaNS, PathPosition pos, XMPPath expandedXPath) { while (pos.stepEnd < pos.path.Length && "/[*".IndexOf(pos.path[pos.stepEnd]) < 0) { pos.stepEnd++; } if (pos.stepEnd == pos.stepBegin) { throw new XMPException("Empty initial XMPPath step", XMPErrorConstants.Badxpath); } string rootProp = VerifyXPathRoot(schemaNS, Sharpen.Runtime.Substring(pos.path, pos.stepBegin, pos.stepEnd)); XMPAliasInfo aliasInfo = XMPMetaFactory.GetSchemaRegistry().FindAlias(rootProp); if (aliasInfo == null) { // add schema xpath step expandedXPath.Add(new XMPPathSegment(schemaNS, XMPPath.SchemaNode)); XMPPathSegment rootStep = new XMPPathSegment(rootProp, XMPPath.StructFieldStep); expandedXPath.Add(rootStep); } else { // add schema xpath step and base step of alias expandedXPath.Add(new XMPPathSegment(aliasInfo.GetNamespace(), XMPPath.SchemaNode)); XMPPathSegment rootStep = new XMPPathSegment(VerifyXPathRoot(aliasInfo.GetNamespace(), aliasInfo.GetPropName()), XMPPath.StructFieldStep); rootStep.SetAlias(true); rootStep.SetAliasForm(aliasInfo.GetAliasForm().GetOptions()); expandedXPath.Add(rootStep); if (aliasInfo.GetAliasForm().IsArrayAltText()) { XMPPathSegment qualSelectorStep = new XMPPathSegment("[?xml:lang='x-default']", XMPPath.QualSelectorStep); qualSelectorStep.SetAlias(true); qualSelectorStep.SetAliasForm(aliasInfo.GetAliasForm().GetOptions()); expandedXPath.Add(qualSelectorStep); } else { if (aliasInfo.GetAliasForm().IsArray()) { XMPPathSegment indexStep = new XMPPathSegment("[1]", XMPPath.ArrayIndexStep); indexStep.SetAlias(true); indexStep.SetAliasForm(aliasInfo.GetAliasForm().GetOptions()); expandedXPath.Add(indexStep); } } } }
/// <summary>Visit all of the top level nodes looking for aliases.</summary> /// <remarks> /// Visit all of the top level nodes looking for aliases. If there is /// no base, transplant the alias subtree. If there is a base and strict /// aliasing is on, make sure the alias and base subtrees match. /// </remarks> /// <param name="tree">the root of the metadata tree</param> /// <param name="options">th parsing options</param> /// <exception cref="Com.Adobe.Xmp.XMPException">Forwards XMP errors</exception> private static void MoveExplicitAliases(XMPNode tree, ParseOptions options) { if (!tree.GetHasAliases()) { return; } tree.SetHasAliases(false); bool strictAliasing = options.GetStrictAliasing(); for (Iterator schemaIt = tree.GetUnmodifiableChildren().Iterator(); schemaIt.HasNext();) { XMPNode currSchema = (XMPNode)schemaIt.Next(); if (!currSchema.GetHasAliases()) { continue; } for (Iterator propertyIt = currSchema.IterateChildren(); propertyIt.HasNext();) { XMPNode currProp = (XMPNode)propertyIt.Next(); if (!currProp.IsAlias()) { continue; } currProp.SetAlias(false); // Find the base path, look for the base schema and root node. XMPAliasInfo info = XMPMetaFactory.GetSchemaRegistry().FindAlias(currProp.GetName()); if (info != null) { // find or create schema XMPNode baseSchema = XMPNodeUtils.FindSchemaNode(tree, info.GetNamespace(), null, true); baseSchema.SetImplicit(false); XMPNode baseNode = XMPNodeUtils.FindChildNode(baseSchema, info.GetPrefix() + info.GetPropName(), false); if (baseNode == null) { if (info.GetAliasForm().IsSimple()) { // A top-to-top alias, transplant the property. // change the alias property name to the base name string qname = info.GetPrefix() + info.GetPropName(); currProp.SetName(qname); baseSchema.AddChild(currProp); // remove the alias property propertyIt.Remove(); } else { // An alias to an array item, // create the array and transplant the property. baseNode = new XMPNode(info.GetPrefix() + info.GetPropName(), info.GetAliasForm().ToPropertyOptions()); baseSchema.AddChild(baseNode); TransplantArrayItemAlias(propertyIt, currProp, baseNode); } } else { if (info.GetAliasForm().IsSimple()) { // The base node does exist and this is a top-to-top alias. // Check for conflicts if strict aliasing is on. // Remove and delete the alias subtree. if (strictAliasing) { CompareAliasedSubtrees(currProp, baseNode, true); } propertyIt.Remove(); } else { // This is an alias to an array item and the array exists. // Look for the aliased item. // Then transplant or check & delete as appropriate. XMPNode itemNode = null; if (info.GetAliasForm().IsArrayAltText()) { int xdIndex = XMPNodeUtils.LookupLanguageItem(baseNode, XMPConstConstants.XDefault); if (xdIndex != -1) { itemNode = baseNode.GetChild(xdIndex); } } else { if (baseNode.HasChildren()) { itemNode = baseNode.GetChild(1); } } if (itemNode == null) { TransplantArrayItemAlias(propertyIt, currProp, baseNode); } else { if (strictAliasing) { CompareAliasedSubtrees(currProp, itemNode, true); } propertyIt.Remove(); } } } } } currSchema.SetHasAliases(false); } }