2009-10-05 57 views
1

这是一个模糊的概念,我一直在脑海里跑过来,如果有一个优雅的解决方法,我很好奇。也许它应该被视为一个思想实验。SVG通过动态XML + XSL

想象一下,您有一个带有相应XSL转换的XML模式,它将XML呈现为浏览器中的SVG。 XSL使用适当的Javascript处理程序生成SVG,最终实现类似编辑的功能,以便用户可以编辑SVG画布上对象的属性或其位置。例如,一个元素可以从一个位置拖到另一个位置。

现在,这并不是特别困难 - 拖/放示例仅仅是改变SVG对象的(x,y)坐标,或者调整大小操作只是简单地改变其宽度或高度。

但是,有没有一种优雅的方式让Javascript工作在源代码的DOM上 XML文档而不是渲染的SVG?你为什么问?好吧,想象你有非常复杂的XSL转换,其中一个属性的修改导致SVG的复杂变化。您希望保持Javascript代码的简单性,同时也是将修改后的XML保存到服务器的简单方法。

这如何可以起到一些可能性:

  1. 源DOM的修改后,只需重新运行XSL转换和替代原来的。 下行:蛮力,潜在的昂贵操作。
  2. 在源和目标XML/SVG中创建id/class命名约定,以便元素可以相互关联,并且仅对新DOM的一部分进行XSL转换。换句话说,修改临时DOM,对其应用XSL,从SVG中删除已更改的元素,然后插入新元素。 缺点:可能无法将XSL应用于临时浏览器内DOM(?)。此外,也许有点复杂或难以维护。

我认为有可能提出一个处理第二种情况的框架,但挑战会使它变得轻量级并且与实际的XML模式没有太大关系。任何想法或其他可能性?或者是否有一种我不知道的做法?

UPDATE:为了澄清,正如我在下面的评论中提到的,这有助于将绘制代码与编辑代码分开。有关这个如何有用的更具体的例子,可以设想一个元素,它决定如何绘制依赖于相邻元素属性的值。最好直接在绘制代码中压缩该逻辑,而不是在编辑代码中复制该逻辑。

回答

2

我们在浏览器中的XML编辑器Xopus中完成了这项工作。你可以看到一个例子here。 我们加载XML源文档,XML模式和输出HTML + SVG的XSLT。在内部,我们将XSLT重写为XSLT',这将允许我们将输出HTML + SVG跟踪回到原来的XML,这是XSL中的上下文,以输出该HTML或SVG节点。这是你所指的框架。

为了便于编辑,我们将光标定位在XSLT输出上,并在键入或插入元素时更新XML DOM。每次更改后,我们将重新运行XSLT。出于性能原因,我们将比较XSLT输出和以前的输出,并将使用HTML DOM操作的更改应用于所见即所得视图。

我们使用另一个XSLT来区分两个XSLT输出。我们可以这样做,因为我们已经修改了原始的XSLT(导致XSLT'),以便为每个输出节点输出唯一且持久的ID。因此,所有新节点都将有新的ID,缺少的ID将被删除。

XSLT'是您提供的原始XSLT的重写版本。它仍然是XSLT,但我们已经添加了一些东西,所以它会输出所有输出节点的ID(我们在另一个XSLT中这样做)。除此之外,它在功能上等同于原始的XSLT。

+0

听说它是可行的有趣。你如何区分两个XSLT输出? – 2010-04-01 22:51:33

+0

或者,您还指“XSLT”是什么意思?你在内部做了些什么,或者我没有找到的既定标准? – 2010-04-03 07:56:42

+0

我们使用另一个XSLT来比较两个XSLT输出。我们可以这样做,因为我们已经修改了原始的XSLT(导致XSLT'),以便为每个输出节点输出唯一且持久的ID。因此,所有新节点都将有新的ID,缺少的ID将被删除。 – Laurens 2010-04-06 09:06:29

0

也许可以使用can AJAX:不是在本地编辑文档,而是将原始XML的编辑命令发送到服务器,再次转换并发送新的SVG。

这里的主要问题是当你更新当前页面上的SVG元素时会发生什么。会拖动还是会感觉平稳?如果不是,那么你可能不得不采用两种方法的混合:使用JavaScript拖动SVG节点,当用户放弃节点时,向服务器发送更新以获得新的SVG。

您将希望避免尝试同步XML和本地SVG中的更新(这意味着要在JavaScript中复制部分XSLT - >停留在一个世界,不要混合)。

+0

虽然主要想法是浏览器会处理转换,并在更改完成后立即进行更新,包括(如您所述)需要像拖放一样平滑的编辑。好处是你已经将绘制代码分离到一个转换中,编辑代码完全可以忽略它。 – 2009-10-05 14:26:47

+0

我明白了;我只是怀疑视觉反馈会在局部变换的重新运行中生存下来。最重要的是,我不知道告诉浏览器再次应用转换:当你的JS运行时,你不再拥有原始文档了,因为它已经被转换了,并且浏览器没有保留副本。 – 2009-10-05 14:43:03

+0

那么,你可以手动加载XML,保留一份副本,并使用transformNode()或JavaScript库来应用JavaScript中的xslt ...然后手动将其添加到你的dom中。但正如你所说,这是问题的速度。 – 2009-10-05 15:12:55