今回のXML変換は連想配列ではなくDOMから変換するものだ。これは、Googleのコードを抜粋したもので、2006年頃に使っていたものだが、DOMはあまり好きではないので捨て置いていた。しかし、この記事が好評なので紹介することにした。さらに連想配列に変換したければjson.jsを使うといいだろう。
dom2xml.html DEMO(ココをクリック)
<dom2xml.html: サンプル>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>DOM2XML</title>
<script type="text/javascript" src="scripts/xmltext.js"></script>
<script type="text/javascript" src="scripts/xmlgetx.js"></script>
<script type="text/javascript">
function test() {
var collection = document.createElement('collection'); // ルートエレメントを作成
collection.setAttribute('title','Java Script XMLDOM test'); // 属性を作成
var membertype = document.createElement('member-type'); // 子要素を作成
membertype.appendChild(document.createTextNode('jpeg')); // 子要素のtextnodeを作成
collection.appendChild(membertype); // 親要素に子要素を追加
var xmltext = xmlText(collection); // xmlのタグを含む形でテキスト化
alert(xmltext);
var xmlvalue = xmlValue(collection); // xmlのタグを除く形でテキスト化
alert(xmlvalue);
var title = xmlGetAttribute(collection, 'title'); // xmlの属性を取得する
alert(title);
var membertype = xmlGetText(collection,'member-type'); // xmlのtextnodeを取得
alert(membertype);
}
</script>
</head>
<body onload="test();"></body>
</html>
<xmlgetx.js: 属性やテキストノードを取得する(クリックでソース参照)>
function xmlGetText(node,tagname) {
var result = node.getElementsByTagName(tagname).item(0).childNodes.item(0).data;
return result;
}
function xmlGetAttribute(node, name) {
// TODO(mesch): This should not be necessary if the DOM is working
// correctly. The DOM is responsible for resolving entities, not the
// application.
var value = node.getAttribute(name);
if (value) {
return xmlResolveEntities(value);
} else {
return value;
}
};
// Split a string s at all occurrences of character c. This is like
// the split() method of the string object, but IE omits empty
// strings, which violates the invariant (s.split(x).join(x) == s).
function stringSplit(s, c) {
var a = s.indexOf(c);
if (a == -1) {
return [ s ];
}
var parts = [];
parts.push(s.substr(0,a));
while (a != -1) {
var a1 = s.indexOf(c, a + 1);
if (a1 != -1) {
parts.push(s.substr(a + 1, a1 - a - 1));
} else {
parts.push(s.substr(a + 1));
}
a = a1;
}
return parts;
}
// Copyright 2005 Google Inc.
// All Rights Reserved
//
// An XML parse and a minimal DOM implementation that just supportes
// the subset of the W3C DOM that is used in the XSLT implementation.
//
// References:
//
// [DOM] W3C DOM Level 3 Core Specification
// <http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/>.
//
//
// Author: Steffen Meschkat <mesch@google.com>
// NOTE: The split() method in IE omits empty result strings. This is
// utterly annoying. So we don't use it here.
// Resolve entities in XML text fragments. According to the DOM
// specification, the DOM is supposed to resolve entity references at
// the API level. I.e. no entity references are passed through the
// API. See "Entities and the DOM core", p.12, DOM 2 Core
// Spec. However, different browsers actually pass very different
// values at the API.
//
function xmlResolveEntities(s) {
var parts = stringSplit(s, '&');
var ret = parts[0];
for (var i = 1; i < parts.length; ++i) {
var rp = stringSplit(parts[i], ';');
if (rp.length == 1) {
// no entity reference: just a & but no ;
ret += parts[i];
continue;
}
var ch;
switch (rp[0]) {
case 'lt':
ch = '<';
break;
case 'gt':
ch = '>';
break;
case 'amp':
ch = '&';
break;
case 'quot':
ch = '"';
break;
case 'apos':
ch = '\'';
break;
case 'nbsp':
ch = String.fromCharCode(160);
break;
default:
// Cool trick: let the DOM do the entity decoding. We assign
// the entity text through non-W3C DOM properties and read it
// through the W3C DOM. W3C DOM access is specified to resolve
// entities.
var span = window.document.createElement('span');
span.innerHTML = '&' + rp[0] + '; ';
ch = span.childNodes[0].nodeValue.charAt(0);
}
ret += ch + rp[1];
}
return ret;
}
<xmltext.js: DOMをXMLテキスト化する>(クリックでソース参照)
// Based on
// <http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247>
var DOM_ELEMENT_NODE = 1;
var DOM_ATTRIBUTE_NODE = 2;
var DOM_TEXT_NODE = 3;
var DOM_CDATA_SECTION_NODE = 4;
var DOM_DOCUMENT_NODE = 9;
var DOM_DOCUMENT_FRAGMENT_NODE = 11;
// Returns the text value if a node; for nodes without children this
// is the nodeValue, for nodes with children this is the concatenation
// of the value of all children.
function xmlValue(node) {
if (!node) {
return '';
}
var ret = '';
if (node.nodeType == DOM_TEXT_NODE ||
node.nodeType == DOM_CDATA_SECTION_NODE ||
node.nodeType == DOM_ATTRIBUTE_NODE) {
ret += node.nodeValue;
} else if (node.nodeType == DOM_ELEMENT_NODE ||
node.nodeType == DOM_DOCUMENT_NODE ||
node.nodeType == DOM_DOCUMENT_FRAGMENT_NODE) {
for (var i = 0; i < node.childNodes.length; ++i) {
ret += arguments.callee(node.childNodes[i]);
}
}
return ret;
}
// Returns the representation of a node as XML text.
function xmlText(node) {
var ret = '';
if (node.nodeType == DOM_TEXT_NODE) {
ret += xmlEscapeText(node.nodeValue);
} else if (node.nodeType == DOM_ELEMENT_NODE) {
// midified by S.Takezaki(to LowerCase)
ret += '<' + node.nodeName.toLowerCase();
for (var i = 0; i < node.attributes.length; ++i) {
var a = node.attributes[i];
// midified by S.Takezaki
if (a && a.nodeName && a.nodeValue && a.nodeName!='contentEditable' ) {
ret += ' ' + a.nodeName.toLowerCase();
ret += '="' + xmlEscapeAttr(a.nodeValue) + '"';
}
}
if (node.childNodes.length == 0) {
ret += '/>';
} else {
ret += '>';
for (var i = 0; i < node.childNodes.length; ++i) {
ret += arguments.callee(node.childNodes[i]);
}
// midified by S.Takezaki(to LowerCase)
ret += '</' + node.nodeName.toLowerCase() + '>';
}
} else if (node.nodeType == DOM_DOCUMENT_NODE ||
node.nodeType == DOM_DOCUMENT_FRAGMENT_NODE) {
for (var i = 0; i < node.childNodes.length; ++i) {
ret += arguments.callee(node.childNodes[i]);
}
}
return ret;
}
// Escape XML special markup chracters: tag delimiter < > and entity
// reference start delimiter &. The escaped string can be used in XML
// text portions (i.e. between tags).
function xmlEscapeText(s) {
return s.replace(/&/g, '&').replace(/</g, '<;').replace(/>/g, '>');
}
// Escape XML special markup characters: tag delimiter < > entity
// reference start delimiter & and quotes ". The escaped string can be
// used in double quoted XML attribute value portions (i.e. in
// attributes within start tags).
function xmlEscapeAttr(s) {
return xmlEscapeText(s).replace(/\"/g, '"');
}
// Escape markup in XML text, but don't touch entity references. The
// escaped string can be used as XML text (i.e. between tags).
function xmlEscapeTags(s) {
return s.replace(/</g, '<;').replace(/>/g, '>');
}
<関連>
DOMをXMLに変換するjQueryプラグイン