火曜日, 7月 08, 2008

【JavaScript】 DOMをXMLに変換 このエントリーを含むはてなブックマーク


 今回の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プラグイン

1 件のコメント:

匿名 さんのコメント...

blue-horse と申します。
掲載されていたDOMからXMLコードを生成するコードを利用させて頂きました。

とても助かりました。
ありがとうございます。

 
© 2006-2015 Virtual Technology
当サイトではGoogle Analyticsを使ってウェブサイトのトラフィック情報を収集しています。詳しくは、プライバシーポリシーを参照してください。