xml2json.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /* Copyright 2015 William Summers, MetaTribal LLC
  2. * adapted from https://developer.mozilla.org/en-US/docs/JXON
  3. *
  4. * Licensed under the MIT License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * https://opensource.org/licenses/MIT
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /**
  17. * @author William Summers
  18. * https://github.com/metatribal/xmlToJSON
  19. */
  20. var DOMParser = require('@xmldom/xmldom').DOMParser;
  21. var xmlToJSON = (function () {
  22. this.version = "1.3.5";
  23. var options = { // set up the default options
  24. mergeCDATA: true, // extract cdata and merge with text
  25. normalize: true, // collapse multiple spaces to single space
  26. stripElemPrefix: true, // for elements of same name in diff namespaces, you can enable namespaces and access the nskey property
  27. };
  28. var prefixMatch = new RegExp(/(?!xmlns)^.*:/);
  29. var trimMatch = new RegExp(/^\s+|\s+$/g);
  30. this.grokType = function (sValue) {
  31. if (/^\s*$/.test(sValue)) {
  32. return null;
  33. }
  34. if (/^(?:true|false)$/i.test(sValue)) {
  35. return sValue.toLowerCase() === "true";
  36. }
  37. if (isFinite(sValue)) {
  38. return parseFloat(sValue);
  39. }
  40. return sValue;
  41. };
  42. this.parseString = function (xmlString, opt) {
  43. if (xmlString) {
  44. var xml = this.stringToXML(xmlString);
  45. if (xml.getElementsByTagName('parsererror').length) {
  46. return null;
  47. } else {
  48. return this.parseXML(xml, opt);
  49. }
  50. } else {
  51. return null;
  52. }
  53. };
  54. this.parseXML = function (oXMLParent, opt) {
  55. // initialize options
  56. for (var key in opt) {
  57. options[key] = opt[key];
  58. }
  59. var vResult = {},
  60. nLength = 0,
  61. sCollectedTxt = "";
  62. // iterate over the children
  63. var childNum = oXMLParent.childNodes.length;
  64. if (childNum) {
  65. for (var oNode, sProp, vContent, nItem = 0; nItem < oXMLParent.childNodes.length; nItem++) {
  66. oNode = oXMLParent.childNodes.item(nItem);
  67. if (oNode.nodeType === 4) {
  68. if (options.mergeCDATA) {
  69. sCollectedTxt += oNode.nodeValue;
  70. }
  71. } /* nodeType is "CDATASection" (4) */
  72. else if (oNode.nodeType === 3) {
  73. sCollectedTxt += oNode.nodeValue;
  74. } /* nodeType is "Text" (3) */
  75. else if (oNode.nodeType === 1) { /* nodeType is "Element" (1) */
  76. if (nLength === 0) {
  77. vResult = {};
  78. }
  79. // using nodeName to support browser (IE) implementation with no 'localName' property
  80. if (options.stripElemPrefix) {
  81. sProp = oNode.nodeName.replace(prefixMatch, '');
  82. } else {
  83. sProp = oNode.nodeName;
  84. }
  85. vContent = xmlToJSON.parseXML(oNode);
  86. if (vResult.hasOwnProperty(sProp)) {
  87. if (vResult[sProp].constructor !== Array) {
  88. vResult[sProp] = [vResult[sProp]];
  89. }
  90. vResult[sProp].push(vContent);
  91. } else {
  92. vResult[sProp] = vContent;
  93. nLength++;
  94. }
  95. }
  96. }
  97. }
  98. if (!Object.keys(vResult).length) {
  99. // vResult = sCollectedTxt.replace(trimMatch, '') || ''; // by carsonxu 修复 getBucket返回的 Key 是 " /" 这种场景
  100. vResult = sCollectedTxt || '';
  101. }
  102. return vResult;
  103. };
  104. // Convert xmlDocument to a string
  105. // Returns null on failure
  106. this.xmlToString = function (xmlDoc) {
  107. try {
  108. var xmlString = xmlDoc.xml ? xmlDoc.xml : (new XMLSerializer()).serializeToString(xmlDoc);
  109. return xmlString;
  110. } catch (err) {
  111. return null;
  112. }
  113. };
  114. // Convert a string to XML Node Structure
  115. // Returns null on failure
  116. this.stringToXML = function (xmlString) {
  117. try {
  118. var xmlDoc = null;
  119. if (window.DOMParser) {
  120. var parser = new DOMParser();
  121. xmlDoc = parser.parseFromString(xmlString, "text/xml");
  122. return xmlDoc;
  123. } else {
  124. xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
  125. xmlDoc.async = false;
  126. xmlDoc.loadXML(xmlString);
  127. return xmlDoc;
  128. }
  129. } catch (e) {
  130. return null;
  131. }
  132. };
  133. return this;
  134. }).call({});
  135. var xml2json = function (xmlString) {
  136. return xmlToJSON.parseString(xmlString);
  137. };
  138. module.exports = xml2json;