- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我将一些数据存储为 XML,并将用户的更改存储为与原始 XML 的差异,因此可以在运行时为用户数据打补丁。
原始 xml 的示例(仅部分):
<module id="">
<title id="">
...
</title>
<actions>
...
</actions>
<zones id="" selected="right">
<zone id="" key="right" name="Right" />
</zones>
</module>
用户差异示例(用户将 selected 的值从右更改为左):
<xd:xmldiff version="1.0" srcDocHash=""
options="IgnoreChildOrder IgnoreNamespaces IgnorePrefixes IgnoreSrcValidation "
fragments="no"
xmlns:xd="http://schemas.microsoft.com/xmltools/2002/xmldiff">
<xd:node match="1">
<xd:node match="3">
<xd:change match="@selected">left</xd:change>
</xd:node>
</xd:node>
</xd:xmldiff>
问题是,补丁会查找 XML 节点的顺序。如果顺序发生变化,则无法再应用 diff,甚至更糟的是,它会被错误地应用。所以我更喜欢用 XID 打补丁。有谁知道用于 XyDiff 的 C# 的高性能库或算法?
最佳答案
我们现在开发了自己的解决方案,效果很好。
我们做了什么:
xml 补丁如下所示:
<patch>
<xmlpatch sortorder="10" visible="true" targetId="{Guid-x}" />
<xmlpatch selected="left" targetId="{Guid-y}" />
<xmlpatch targetId="{Guid-z}">true</xmlpatch>
</patch>
生成补丁 xml 的代码非常简单。我们遍历所有 xml 节点,并为每个节点遍历所有属性。如果节点的属性或值与原始节点不同,我们将生成具有该属性或值的补丁节点。请注意,代码是一晚上写的;)
public static XDocument GenerateDiffGram(XDocument allUserDocument, XDocument runtimeDocument)
{
XDocument diffDocument = new XDocument();
XElement root = new XElement("patch");
AddElements(root, runtimeDocument, allUserDocument.Root);
diffDocument.Add(root);
return diffDocument;
}
private static void AddElements(XElement rootPatch, XDocument runtimeDocument, XElement allUserElement)
{
XElement patchElem = null;
if (allUserElement.Attribute("id") != null
&& !string.IsNullOrWhiteSpace(allUserElement.Attribute("id").Value))
{
// find runtime element by id
XElement runtimeElement = (from e in runtimeDocument.Descendants(allUserElement.Name)
where e.Attribute("id") != null
&& e.Attribute("id").Value.Equals(allUserElement.Attribute("id").Value)
select e).FirstOrDefault();
// create new patch node
patchElem = new XElement("xmlpatch");
// check for changed attributes
foreach (var allUserAttribute in allUserElement.Attributes())
{
XAttribute runtimeAttribute = runtimeElement.Attribute(allUserAttribute.Name);
if (!allUserAttribute.Value.Equals(runtimeAttribute.Value))
{
patchElem.SetAttributeValue(allUserAttribute.Name, runtimeAttribute.Value);
}
}
// check for changed value
if (!allUserElement.HasElements
&& !allUserElement.Value.Equals(runtimeElement.Value))
{
patchElem.Value = runtimeElement.Value;
}
}
// loop through all children to find changed values
foreach (var childElement in allUserElement.Elements())
{
AddElements(rootPatch, runtimeDocument, childElement);
}
// add node for changed value
if (patchElem != null
&& (patchElem.HasAttributes
|| !string.IsNullOrEmpty(patchElem.Value)))
{
patchElem.SetAttributeValue("targetId", allUserElement.Attribute("id").Value);
rootPatch.AddFirst(patchElem);
}
}
在运行时,我们修补保存在补丁 xml 中的更改。我们通过 targetid 获取原始节点并覆盖属性和值。
public static XDocument Patch(XDocument runtimeDocument, XDocument userDocument, string modulePath, string userName)
{
XDocument patchDocument = new XDocument(userDocument);
foreach (XElement element in patchDocument.Element("patch").Elements())
{
// get id of the element
string idAttribute = element.Attribute("targetId").Value;
// get element with id from allUserDocument
XElement sharedElement = (from e in runtimeDocument.Descendants()
where e.Attribute("id") != null
&& e.Attribute("id").Value.Equals(idAttribute)
select e).FirstOrDefault();
// element doesn't exist anymore. Maybe the admin has deleted the element
if (sharedElement == null)
{
// delete the element from the user patch
element.Remove();
}
else
{
// set attributes to user values
foreach (XAttribute attribute in element.Attributes())
{
if (!attribute.Name.LocalName.Equals("targetId"))
{
sharedElement.SetAttributeValue(attribute.Name, attribute.Value);
}
}
// set element value
if (!string.IsNullOrEmpty(element.Value))
{
sharedElement.Value = element.Value;
}
}
}
// user patch has changed (nodes deleted by the admin)
if (!patchDocument.ToString().Equals(userDocument.ToString()))
{
// save back the changed user patch
using (PersonalizationProvider provider = new PersonalizationProvider())
{
provider.SaveUserPersonalization(modulePath, userName, patchDocument);
}
}
return runtimeDocument;
}
关于c# - 在 C# 中寻找高性能的 XyDiff 端口(带有 XID 的 XML 差异补丁),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10983718/
我有一个 Web 应用程序从 MQ 收集数据并保存在数据库中。使用 Spring JMS 监听器容器从 MQ 读取消息,并使用 hibernate 模板将这些消息保留在 XA Oracle 数据源上。
我找不到如何将 xid(交易 ID 类型)列设置为在表中唯一。它提示 btree 缺少类方法,我不知道如何解决它。 这是使用 PostgreSQL 9.0。 在这些论坛或互联网上找不到任何类似的问题。
我有以下 Python 2.7/PyGObject 3.0/PyGST 0.10 模块: from gi.repository import Gtk, Gdk, GdkPixbuf import pa
我想在我的 MySQL 5.6 服务器上执行 mysql-命令: mysql> XA ROLLBACK xid; 我尝试从此命令获取 xid: mysql> XA RECOVER; 结果如下: 我向社
我正在尝试在 Python 3.6 中使用 python-vlc 和 Gtk 创建一个 GUI 应用程序。但是当我尝试访问我的 GtkDrawingArea 小部件的 xid(将它与我的播放器屏幕绑定
我正在调查 Postgres 数据库上经常执行的查询,以帮助减少 XID 的使用。我可以使用 pg_stat_statements 获取执行的查询列表和调用次数,但它不包括因违反唯一约束等原因而失败的
有没有办法得到transactionid(xid)来自 SQL 查询,还是来自 plpgsql 函数体? PostgreSQL 9.3 版本 最佳答案 http://www.postgresql.or
我正在使用 Spring 3.0.5、Hibernate 3.6.7、Atomikos TransactionEssentials 3.7.0 和 MySQL 5.5 我最近遇到了一个问题,我的连接池
在启动我的 Spring 应用程序时收到上述警告。 WARN com.atomikos.recovery.xa.XaResourceRecoveryManager - Error while retr
如何从 xid(X 窗口标识符)获取 pid?如何获取给定 pid 的 xid 列表? (假设所有应用程序都以 DISPLAY=:0 运行,没有使用网络透明性) 我期待这样的事情: 挖掘/proc/$
我迷失在版本 3 中。在 python2+gdk2 中是: #!/usr/bin/env python2 import gtk gtk.gdk.window_process_all_updates()
有两次,当我使用 4x1080ti 完成模型训练时,服务器宕机了。为什么服务器崩溃了? 我收到系统日志并发现有关 Nvidia 驱动程序或 GPU 的问题。 系统日志:(和 nvidia-bug-re
我正在将 Linux 桌面应用程序移植到 Emberjs在 Electron应用程序以允许更自定义的用户界面。虽然大多数控件都非常适合 HTML 和 CSS,但我需要能够在 Electron 窗口内绘
这是我的用户模型 public class Users { private long id; private String userName; private String n
将 deviceToken 注册到 Xtify Manager 后,如何知道 xid 何时可用? 我正在这样做: - (BOOL)application:(UIApplication *)applic
简而言之:这是 How to get Gdk window from xid? 的重复,但在 Wayland 下。 在我将 Debian 从 Stretch 更新到 Buster 之前,类似以下的代码
PostgreSQL 9.6。服务器最近从突然断电中恢复过来。 当在 pgadmin 中为表 Current 运行 select 命令时,它显示 invalid page in block 64553
很抱歉,如果这个问题已经有人回答了,但我自己找不到。 我在 plgsql 中有这样一个函数: CREATE OR REPLACE FUNCTION collect_transaction_data(x
我正在编写一个 Gtk2 应用程序,除其他外,它需要让 Mplayer 将视频播放到 GtkDrawingArea 中。据我所知,如果可以找到 GtkDrawingArea 的 XID 并将其作为参数
XID 和 TX 列中的分数代表什么。这是 postgres 的 pgadmin 工具的屏幕截图。 我明白 TX 和 XID 分别表示交易和交易 ID,但是我不明白小数符号是什么意思。 最佳答案 虚拟
我是一名优秀的程序员,十分优秀!