/// <summary> /// Searches for a qualifier selector in a node: /// [?qualName="value"] - an element in an array, chosen by a qualifier value. /// </summary> /// <remarks> /// 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. /// </remarks> /// <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, int aliasForm) { if (XmpConstants.XmlLang.Equals(qualName)) { qualValue = Utils.NormalizeLangValue(qualValue); var index = LookupLanguageItem(arrayNode, qualValue); if (index < 0 && (aliasForm & AliasOptions.PropArrayAltText) > 0) { var langNode = new XmpNode(XmpConstants.ArrayItemName, null); var xdefault = new XmpNode(XmpConstants.XmlLang, XmpConstants.XDefault, null); langNode.AddQualifier(xdefault); arrayNode.AddChild(1, langNode); return(1); } return(index); } for (var index = 1; index < arrayNode.GetChildrenLength(); index++) { var currItem = arrayNode.GetChild(index); for (var it = currItem.IterateQualifier(); it.HasNext();) { var qualifier = (XmpNode)it.Next(); if (qualName.Equals(qualifier.Name) && qualValue.Equals(qualifier.Value)) { return(index); } } } return(-1); }
/// <exception cref="XmpException"/> public IXmpProperty GetLocalizedText(string schemaNs, string altTextName, string genericLang, string specificLang) { ParameterAsserts.AssertSchemaNs(schemaNs); ParameterAsserts.AssertArrayName(altTextName); ParameterAsserts.AssertSpecificLang(specificLang); genericLang = genericLang != null?Utils.NormalizeLangValue(genericLang) : null; specificLang = Utils.NormalizeLangValue(specificLang); var arrayPath = XmpPathParser.ExpandXPath(schemaNs, altTextName); var arrayNode = XmpNodeUtils.FindNode(_tree, arrayPath, false, null); if (arrayNode == null) { return(null); } var result = XmpNodeUtils.ChooseLocalizedText(arrayNode, genericLang, specificLang); var match = (int)result[0]; var itemNode = (XmpNode)result[1]; if (match != XmpNodeUtils.CltNoValues) { return(new XmpProperty407(itemNode)); } return(null); }
/// <summary>This is setting the value of a leaf node.</summary> /// <param name="node">an XMPNode</param> /// <param name="value">a value</param> internal static void SetNodeValue(XmpNode node, object value) { var strValue = SerializeNodeValue(value); node.Value = node.Options.IsQualifier && node.Name == XmpConstants.XmlLang ? Utils.NormalizeLangValue(strValue) : strValue; }
/// <summary>This is setting the value of a leaf node.</summary> /// <param name="node">an XMPNode</param> /// <param name="value">a value</param> internal static void SetNodeValue(XmpNode node, object value) { var strValue = SerializeNodeValue(value); if (!(node.Options.IsQualifier && XmpConstants.XmlLang.Equals(node.Name))) { node.Value = strValue; } else { node.Value = Utils.NormalizeLangValue(strValue); } }
/// <exception cref="XmpException"/> public void SetLocalizedText(string schemaNs, string altTextName, string genericLang, string specificLang, string itemValue, PropertyOptions options) { ParameterAsserts.AssertSchemaNs(schemaNs); ParameterAsserts.AssertArrayName(altTextName); ParameterAsserts.AssertSpecificLang(specificLang); genericLang = genericLang != null?Utils.NormalizeLangValue(genericLang) : null; specificLang = Utils.NormalizeLangValue(specificLang); var arrayPath = XmpPathParser.ExpandXPath(schemaNs, altTextName); // Find the array node and set the options if it was just created. var arrayNode = XmpNodeUtils.FindNode(_tree, arrayPath, true, new PropertyOptions(PropertyOptions.ArrayFlag | PropertyOptions.ArrayOrderedFlag | PropertyOptions.ArrayAlternateFlag | PropertyOptions.ArrayAltTextFlag)); if (arrayNode == null) { throw new XmpException("Failed to find or create array node", XmpErrorCode.BadXPath); } if (!arrayNode.Options.IsArrayAltText) { if (!arrayNode.HasChildren && arrayNode.Options.IsArrayAlternate) { arrayNode.Options.IsArrayAltText = true; } else { throw new XmpException("Specified property is no alt-text array", XmpErrorCode.BadXPath); } } // Make sure the x-default item, if any, is first. var haveXDefault = false; XmpNode xdItem = null; for (var it = arrayNode.IterateChildren(); it.HasNext();) { var currItem = (XmpNode)it.Next(); if (!currItem.HasQualifier || !XmpConstants.XmlLang.Equals(currItem.GetQualifier(1).Name)) { throw new XmpException("Language qualifier must be first", XmpErrorCode.BadXPath); } if (XmpConstants.XDefault.Equals(currItem.GetQualifier(1).Value)) { xdItem = currItem; haveXDefault = true; break; } } // Moves x-default to the beginning of the array if (xdItem != null && arrayNode.GetChildrenLength() > 1) { arrayNode.RemoveChild(xdItem); arrayNode.AddChild(1, xdItem); } // Find the appropriate item. // chooseLocalizedText will make sure the array is a language // alternative. var result = XmpNodeUtils.ChooseLocalizedText(arrayNode, genericLang, specificLang); var match = (int)result[0]; var itemNode = (XmpNode)result[1]; var specificXDefault = XmpConstants.XDefault.Equals(specificLang); switch (match) { case XmpNodeUtils.CltNoValues: { // Create the array items for the specificLang and x-default, with // x-default first. XmpNodeUtils.AppendLangItem(arrayNode, XmpConstants.XDefault, itemValue); haveXDefault = true; if (!specificXDefault) { XmpNodeUtils.AppendLangItem(arrayNode, specificLang, itemValue); } break; } case XmpNodeUtils.CltSpecificMatch: { if (!specificXDefault) { // Update the specific item, update x-default if it matches the // old value. if (haveXDefault && xdItem != itemNode && xdItem != null && xdItem.Value.Equals(itemNode.Value)) { xdItem.Value = itemValue; } // ! Do this after the x-default check! itemNode.Value = itemValue; } else { // Update all items whose values match the old x-default value. Debug.Assert(haveXDefault && xdItem == itemNode); for (var it1 = arrayNode.IterateChildren(); it1.HasNext();) { var currItem = (XmpNode)it1.Next(); if (currItem == xdItem || !currItem.Value.Equals(xdItem != null ? xdItem.Value : null)) { continue; } currItem.Value = itemValue; } // And finally do the x-default item. if (xdItem != null) { xdItem.Value = itemValue; } } break; } case XmpNodeUtils.CltSingleGeneric: { // Update the generic item, update x-default if it matches the old // value. if (haveXDefault && xdItem != itemNode && xdItem != null && xdItem.Value.Equals(itemNode.Value)) { xdItem.Value = itemValue; } itemNode.Value = itemValue; // ! Do this after // the x-default // check! break; } case XmpNodeUtils.CltMultipleGeneric: { // Create the specific language, ignore x-default. XmpNodeUtils.AppendLangItem(arrayNode, specificLang, itemValue); if (specificXDefault) { haveXDefault = true; } break; } case XmpNodeUtils.CltXdefault: { // Create the specific language, update x-default if it was the only // item. if (xdItem != null && arrayNode.GetChildrenLength() == 1) { xdItem.Value = itemValue; } XmpNodeUtils.AppendLangItem(arrayNode, specificLang, itemValue); break; } case XmpNodeUtils.CltFirstItem: { // Create the specific language, don't add an x-default item. XmpNodeUtils.AppendLangItem(arrayNode, specificLang, itemValue); if (specificXDefault) { haveXDefault = true; } break; } default: { // does not happen under normal circumstances throw new XmpException("Unexpected result from ChooseLocalizedText", XmpErrorCode.InternalFailure); } } // Add an x-default at the front if needed. if (!haveXDefault && arrayNode.GetChildrenLength() == 1) { XmpNodeUtils.AppendLangItem(arrayNode, XmpConstants.XDefault, itemValue); } }