3

假设您在 JavaScript 中获得了单个 DOM 元素或文档(例如 window.document),您将如何将其转换为有效的 XML?

更具体地说,对于我的示例,我有一个显示 SVG 的网页,这个 SVG 有很多 JavaScript 来允许交互。这是一个图表显示,可以让您放大图表,甚至进行一些转换。现在用户关闭这个想要有一个“保存图像”按钮。我想这样做的方式是获取 SVG 元素的文档节点,并将其转换为 XML,然后将其发送到服务器,然后服务器返回包含 SVG 文档或 PNG 图像的页面。

这一切都在 FireFox 上运行(目前这是用户的要求,尽管它在 Safari 和 Chrome 中也可以正常工作)。在网页的 Firefox 中,我已将 SVG 文档作为对象元素包含在内。在 javascript 中,我可以访问该对象 contentDocument,它指的是 XML 页面的根。它包含 XML 版本、文档标记和具有所有属性的根 svg 标记。

也许有人已经解决了这个问题,所以我可以复制他们的代码。也许有人知道在哪里寻找萤火虫来实现这一目标。或者也许已经有 DOM 方法可以做到这一点。

4

2 回答 2

4

有一个非标准的 API 对象:XMLSerializer(它不是标准的,但在除 IE 浏览器之外的所有浏览器中都实现了)。

它的 serializeToString 方法需要传递 DOMNode 对象。

var sXML = new XMLSerializer().serializeToString(document.body);

在 Internet Explorer 中,没有办法为 HTML 检索正确的 XML,除非获取 .outerHTML 并修复序列化为 HTML 所带来的所有问题(例如属性中缺少引号,而不是闭合标签等)

于 2009-05-06T13:59:31.770 回答
1

明天我将不得不研究 XMLSerializer。这是我最终编写的代码,以防万一有人感兴趣(未知节点需要原型和 FireBug):

function extractXML(node) {
    switch (node.nodeType) {
        case 1: return extractNodeXML(node);
        case 2: return extractAttributeXML(node);
        // 3 = Text node
        case 3: return node.nodeValue;
        // 8 = Comment node - ignore
        case 8: return "";
        case 9: return extractDocumentNodeXML(node);
        case 10: return extractDocumentTypeXML(node);
        default: console.log(node); return "Unkwon type: "+node.nodeType;
    }
}
function extractNodeXML(node) {
    var xml = "<"+node.nodeName;
    $A(node.attributes).each(function (node) {xml += " "+extractXML(node)});
    xml +=">"
    $A(node.childNodes).each(function (node) {xml += extractXML(node)});
    xml += "</"+node.nodeName+">"
    return xml;
}
function extractAttributeXML(node) {
    return node.nodeName+"=\""+node.nodeValue+"\""
}
function extractDocumentNodeXML(node) {
    var xml = "<?xml version=\""+node.xmlVersion+"\" encoding=\""+node.xmlEncoding+"\"?>"
    $A(node.childNodes).each(function (node) {xml += extractXML(node)});
    return xml;
}
function extractDocumentTypeXML(node) {
    return "<!DOCTYPE "+node.name+" PUBLIC \""+node.publicId+"\" \""+node.systemId+"\">"
}
于 2009-05-06T14:29:19.730 回答