private void UpdateDomFromDataSet(DataSet data, string elementName,XmlDocument targetDom, HashSet<Tuple<string, string>> itemsToDelete)
{
try
{
var query = String.Format("//{0}[(@data-book or @data-collection or @data-library or @data-book-attributes)]", elementName);
var nodesOfInterest = targetDom.SafeSelectNodes(query);
foreach (XmlElement node in nodesOfInterest)
{
var key = node.GetAttribute("data-book").Trim();
if (key == string.Empty)
{
key = node.GetAttribute("data-book-attributes").Trim();
if (key != string.Empty)
{
UpdateAttributes(data, node, key);
continue;
}
key = node.GetAttribute("data-collection").Trim();
if (key == string.Empty)
{
key = node.GetAttribute("data-library").Trim(); //"library" is the old name for what is now "collection"
}
}
if (string.IsNullOrEmpty(key)) continue;
if (data.TextVariables.ContainsKey(key))
{
if (UpdateImageFromDataSet(data, node, key)) continue;
var lang = node.GetOptionalStringAttribute("lang", "*");
if (lang == "N1" || lang == "N2" || lang == "V")
lang = data.WritingSystemAliases[lang];
// //see comment later about the inability to clear a value. TODO: when we re-write Bloom, make sure this is possible
// if(data.TextVariables[key].TextAlternatives.Forms.Length==0)
// {
// //no text forms == desire to remove it. THe multitextbase prohibits empty strings, so this is the best we can do: completly remove the item.
// targetDom.RemoveChild(node);
// }
// else
if (!string.IsNullOrEmpty(lang)) //if we don't even have this language specified (e.g. no national language), the give up
{
//Ideally, we have this string, in this desired language.
var s = data.TextVariables[key].TextAlternatives.GetBestAlternativeString(new[] {lang, "*"});
if(KeysOfVariablesThatAreUrlEncoded.Contains(key))
{
Debug.Assert(!s.Contains("&"),"In memory, all image urls should be encoded such that & is just &.");
}
//But if not, maybe we should copy one in from another national language
if (string.IsNullOrEmpty(s))
s = PossiblyCopyFromAnotherLanguage(node, lang, data, key);
//NB: this was the focus of a multi-hour bug search, and it's not clear that I got it right.
//The problem is that the title page has N1 and n2 alternatives for title, the cover may not.
//the gather page was gathering no values for those alternatives (why not), and so GetBestAlternativeSTring
//was giving "", which we then used to remove our nice values.
//REVIEW: what affect will this have in other pages, other circumstances. Will it make it impossible to clear a value?
//Hoping not, as we are differentiating between "" and just not being in the multitext at all.
//don't overwrite a datadiv alternative with empty just becuase this page has no value for it.
if (s == "" && !data.TextVariables[key].TextAlternatives.ContainsAlternative(lang))
continue;
//hack: until I think of a more elegant way to avoid repeating the language name in N2 when it's the exact same as N1...
if (data.WritingSystemAliases.Count != 0 && lang == data.WritingSystemAliases["N2"] &&
s ==
data.TextVariables[key].TextAlternatives.GetBestAlternativeString(new[]
{
data.
WritingSystemAliases
["N1"]
, "*"
}))
{
s = ""; //don't show it in N2, since it's the same as N1
}
SetInnerXmlPreservingLabel(key, node, s);
}
}
else if (!HtmlDom.IsImgOrSomethingWithBackgroundImage(node))
{
// See whether we need to delete something
var lang = node.GetOptionalStringAttribute("lang", "*");
if (lang == "N1" || lang == "N2" || lang == "V")
lang = data.WritingSystemAliases[lang];
if (itemsToDelete.Contains(Tuple.Create(key, lang)))
{
SetInnerXmlPreservingLabel(key, node, "");// a later process may remove node altogether.
}
}
}
}
catch (Exception error)
{
throw new ApplicationException(
"Error in UpdateDomFromDataSet(," + elementName + "). RawDom was:\r\n" +
targetDom.OuterXml, error);
}
}