| 3690 | exports.readString = readString; |
| 3691 | |
| 3692 | function readString(xmlString, namespaceMap) { |
| 3693 | namespaceMap = namespaceMap || {}; |
| 3694 | |
| 3695 | var finished = false; |
| 3696 | var parser = sax.parser(true, {xmlns: true, position: false}); |
| 3697 | |
| 3698 | var rootElement = {children: []}; |
| 3699 | var currentElement = rootElement; |
| 3700 | var stack = []; |
| 3701 | |
| 3702 | var deferred = promises.defer(); |
| 3703 | |
| 3704 | parser.onopentag = function(node) { |
| 3705 | var attributes = mapObject(node.attributes, function(attribute) { |
| 3706 | return attribute.value; |
| 3707 | }, mapName); |
| 3708 | |
| 3709 | var element = new Element(mapName(node), attributes); |
| 3710 | currentElement.children.push(element); |
| 3711 | stack.push(currentElement); |
| 3712 | currentElement = element; |
| 3713 | }; |
| 3714 | |
| 3715 | function mapName(node) { |
| 3716 | if (node.uri) { |
| 3717 | var mappedPrefix = namespaceMap[node.uri]; |
| 3718 | var prefix; |
| 3719 | if (mappedPrefix) { |
| 3720 | prefix = mappedPrefix + ":"; |
| 3721 | } else { |
| 3722 | prefix = "{" + node.uri + "}"; |
| 3723 | } |
| 3724 | return prefix + node.local; |
| 3725 | } else { |
| 3726 | return node.local; |
| 3727 | } |
| 3728 | } |
| 3729 | |
| 3730 | parser.onclosetag = function(node) { |
| 3731 | currentElement = stack.pop(); |
| 3732 | }; |
| 3733 | |
| 3734 | parser.ontext = function(text) { |
| 3735 | if (currentElement !== rootElement) { |
| 3736 | currentElement.children.push(nodes.text(text)); |
| 3737 | } |
| 3738 | }; |
| 3739 | |
| 3740 | parser.onend = function() { |
| 3741 | if (!finished) { |
| 3742 | finished = true; |
| 3743 | deferred.resolve(rootElement.children[0]); |
| 3744 | } |
| 3745 | }; |
| 3746 | |
| 3747 | parser.onerror = function(error) { |
| 3748 | if (!finished) { |
| 3749 | finished = true; |