public static void Replace(PwDatabase pd, XmlReplaceOptions opt) { if (pd == null) { Debug.Assert(false); return; } if (opt == null) { Debug.Assert(false); return; } StatusProgressForm dlg = null; try { if ((opt.Flags & XmlReplaceFlags.StatusUI) != XmlReplaceFlags.None) { dlg = StatusProgressForm.ConstructEx(KPRes.XmlReplace, true, false, opt.ParentForm, KPRes.XmlReplace + "..."); } PerformXmlReplace(pd, opt, dlg); } finally { if (dlg != null) { StatusProgressForm.DestroyEx(dlg); } } }
private static void ApplyReplace(XPathNavigator xpNav, XmlReplaceOptions opt, Regex rxFind) { string strData; if (opt.Data == XmlReplaceData.InnerText) { strData = xpNav.Value; } else if (opt.Data == XmlReplaceData.InnerXml) { strData = xpNav.InnerXml; } else if (opt.Data == XmlReplaceData.OuterXml) { strData = xpNav.OuterXml; } else { return; } if (strData == null) { Debug.Assert(false); strData = string.Empty; } string str = null; if (rxFind != null) { str = rxFind.Replace(strData, opt.ReplaceText); } else { if ((opt.Flags & XmlReplaceFlags.CaseSensitive) != XmlReplaceFlags.None) { str = strData.Replace(opt.FindText, opt.ReplaceText); } else { str = StrUtil.ReplaceCaseInsensitive(strData, opt.FindText, opt.ReplaceText); } } if ((str != null) && (str != strData)) { if (opt.Data == XmlReplaceData.InnerText) { xpNav.SetValue(str); } else if (opt.Data == XmlReplaceData.InnerXml) { xpNav.InnerXml = str; } else if (opt.Data == XmlReplaceData.OuterXml) { xpNav.OuterXml = str; } else { Debug.Assert(false); } } }
private static void PerformXmlReplace(PwDatabase pd, XmlReplaceOptions opt, IStatusLogger sl) { if (opt.SelectNodesXPath.Length == 0) { return; } if (opt.Operation == XmlReplaceOp.None) { return; } bool bRemove = (opt.Operation == XmlReplaceOp.RemoveNodes); bool bReplace = (opt.Operation == XmlReplaceOp.ReplaceData); bool bMatchCase = ((opt.Flags & XmlReplaceFlags.CaseSensitive) != XmlReplaceFlags.None); bool bRegex = ((opt.Flags & XmlReplaceFlags.Regex) != XmlReplaceFlags.None); Regex rxFind = null; if (bReplace && bRegex) { rxFind = new Regex(opt.FindText, (bMatchCase ? RegexOptions.None : RegexOptions.IgnoreCase)); } EnsureStandardFieldsExist(pd); KdbxFile kdbxOrg = new KdbxFile(pd); MemoryStream msOrg = new MemoryStream(); kdbxOrg.Save(msOrg, null, KdbxFormat.PlainXml, sl); byte[] pbXml = msOrg.ToArray(); msOrg.Close(); string strXml = StrUtil.Utf8.GetString(pbXml); XmlDocument xd = XmlUtilEx.CreateXmlDocument(); xd.LoadXml(strXml); XPathNavigator xpNavRoot = xd.CreateNavigator(); XPathNodeIterator xpIt = xpNavRoot.Select(opt.SelectNodesXPath); // XPathNavigators must be cloned to make them independent List <XPathNavigator> lNodes = new List <XPathNavigator>(); while (xpIt.MoveNext()) { lNodes.Add(xpIt.Current.Clone()); } if (lNodes.Count == 0) { return; } for (int i = lNodes.Count - 1; i >= 0; --i) { if ((sl != null) && !sl.ContinueWork()) { return; } XPathNavigator xpNav = lNodes[i]; if (bRemove) { xpNav.DeleteSelf(); } else if (bReplace) { ApplyReplace(xpNav, opt, rxFind); } else { Debug.Assert(false); } // Unknown action } MemoryStream msMod = new MemoryStream(); using (XmlWriter xw = XmlUtilEx.CreateXmlWriter(msMod)) { xd.Save(xw); } byte[] pbMod = msMod.ToArray(); msMod.Close(); PwDatabase pdMod = new PwDatabase(); msMod = new MemoryStream(pbMod, false); try { KdbxFile kdbxMod = new KdbxFile(pdMod); kdbxMod.Load(msMod, KdbxFormat.PlainXml, sl); } catch (Exception) { throw new Exception(KPRes.XmlModInvalid + MessageService.NewParagraph + KPRes.OpAborted + MessageService.NewParagraph + KPRes.DbNoModBy.Replace(@"{PARAM}", @"'" + KPRes.XmlReplace + @"'")); } finally { msMod.Close(); } PrepareModDbForMerge(pdMod, pd); pd.Modified = true; pd.UINeedsIconUpdate = true; pd.MergeIn(pdMod, PwMergeMethod.Synchronize, sl); }
private static void ApplyReplace(XPathNavigator xpNav, XmlReplaceOptions opt, Regex rxFind) { string strData; if(opt.Data == XmlReplaceData.InnerText) strData = xpNav.Value; else if(opt.Data == XmlReplaceData.InnerXml) strData = xpNav.InnerXml; else if(opt.Data == XmlReplaceData.OuterXml) strData = xpNav.OuterXml; else return; if(strData == null) { Debug.Assert(false); strData = string.Empty; } string str = null; if(rxFind != null) str = rxFind.Replace(strData, opt.ReplaceText); else { if((opt.Flags & XmlReplaceFlags.CaseSensitive) != XmlReplaceFlags.None) str = strData.Replace(opt.FindText, opt.ReplaceText); else str = StrUtil.ReplaceCaseInsensitive(strData, opt.FindText, opt.ReplaceText); } if((str != null) && (str != strData)) { if(opt.Data == XmlReplaceData.InnerText) xpNav.SetValue(str); else if(opt.Data == XmlReplaceData.InnerXml) xpNav.InnerXml = str; else if(opt.Data == XmlReplaceData.OuterXml) xpNav.OuterXml = str; else { Debug.Assert(false); } } }
private static void PerformXmlReplace(PwDatabase pd, XmlReplaceOptions opt, IStatusLogger sl) { if(opt.SelectNodesXPath.Length == 0) return; if(opt.Operation == XmlReplaceOp.None) return; bool bRemove = (opt.Operation == XmlReplaceOp.RemoveNodes); bool bReplace = (opt.Operation == XmlReplaceOp.ReplaceData); bool bMatchCase = ((opt.Flags & XmlReplaceFlags.CaseSensitive) != XmlReplaceFlags.None); bool bRegex = ((opt.Flags & XmlReplaceFlags.Regex) != XmlReplaceFlags.None); Regex rxFind = null; if(bReplace && bRegex) rxFind = new Regex(opt.FindText, (bMatchCase ? RegexOptions.None : RegexOptions.IgnoreCase)); EnsureStandardFieldsExist(pd); KdbxFile kdbxOrg = new KdbxFile(pd); MemoryStream msOrg = new MemoryStream(); kdbxOrg.Save(msOrg, null, KdbxFormat.PlainXml, sl); byte[] pbXml = msOrg.ToArray(); msOrg.Close(); string strXml = StrUtil.Utf8.GetString(pbXml); XmlDocument xd = new XmlDocument(); xd.LoadXml(strXml); XPathNavigator xpNavRoot = xd.CreateNavigator(); XPathNodeIterator xpIt = xpNavRoot.Select(opt.SelectNodesXPath); // XPathNavigators must be cloned to make them independent List<XPathNavigator> lNodes = new List<XPathNavigator>(); while(xpIt.MoveNext()) lNodes.Add(xpIt.Current.Clone()); if(lNodes.Count == 0) return; for(int i = lNodes.Count - 1; i >= 0; --i) { if((sl != null) && !sl.ContinueWork()) return; XPathNavigator xpNav = lNodes[i]; if(bRemove) xpNav.DeleteSelf(); else if(bReplace) ApplyReplace(xpNav, opt, rxFind); else { Debug.Assert(false); } // Unknown action } MemoryStream msMod = new MemoryStream(); XmlWriterSettings xws = new XmlWriterSettings(); xws.Encoding = StrUtil.Utf8; xws.Indent = true; xws.IndentChars = "\t"; XmlWriter xw = XmlWriter.Create(msMod, xws); xd.Save(xw); byte[] pbMod = msMod.ToArray(); msMod.Close(); PwDatabase pdMod = new PwDatabase(); msMod = new MemoryStream(pbMod, false); try { KdbxFile kdbxMod = new KdbxFile(pdMod); kdbxMod.Load(msMod, KdbxFormat.PlainXml, sl); } catch(Exception) { throw new Exception(KPRes.XmlModInvalid + MessageService.NewParagraph + KPRes.OpAborted + MessageService.NewParagraph + KPRes.DbNoModBy.Replace(@"{PARAM}", @"'" + KPRes.XmlReplace + @"'")); } finally { msMod.Close(); } PrepareModDbForMerge(pdMod, pd); pd.Modified = true; pd.UINeedsIconUpdate = true; pd.MergeIn(pdMod, PwMergeMethod.Synchronize, sl); }
public static void Replace(PwDatabase pd, XmlReplaceOptions opt) { if(pd == null) { Debug.Assert(false); return; } if(opt == null) { Debug.Assert(false); return; } StatusProgressForm dlg = null; try { if((opt.Flags & XmlReplaceFlags.StatusUI) != XmlReplaceFlags.None) dlg = StatusProgressForm.ConstructEx(KPRes.XmlReplace, true, false, opt.ParentForm, KPRes.XmlReplace + "..."); PerformXmlReplace(pd, opt, dlg); } finally { if(dlg != null) StatusProgressForm.DestroyEx(dlg); } }
private void OnBtnOK(object sender, EventArgs e) { this.Enabled = false; try { XmlReplaceOptions opt = new XmlReplaceOptions(); XmlReplaceFlags f = XmlReplaceFlags.StatusUI; opt.ParentForm = this; opt.SelectNodesXPath = m_tbSelNodes.Text; if(m_rbRemove.Checked) opt.Operation = XmlReplaceOp.RemoveNodes; else if(m_rbReplace.Checked) opt.Operation = XmlReplaceOp.ReplaceData; else { Debug.Assert(false); } if(m_rbInnerText.Checked) opt.Data = XmlReplaceData.InnerText; else if(m_rbInnerXml.Checked) opt.Data = XmlReplaceData.InnerXml; else if(m_rbOuterXml.Checked) opt.Data = XmlReplaceData.OuterXml; else { Debug.Assert(false); } if(m_cbCase.Checked) f |= XmlReplaceFlags.CaseSensitive; if(m_cbRegex.Checked) f |= XmlReplaceFlags.Regex; opt.FindText = m_tbMatch.Text; opt.ReplaceText = m_tbReplace.Text; opt.Flags = f; XmlUtil.Replace(m_pd, opt); this.Enabled = true; } catch(Exception ex) { this.Enabled = true; MessageService.ShowWarning(ex.Message); this.DialogResult = DialogResult.None; } }