mirror of
https://github.com/apache/cordova-android.git
synced 2026-05-30 00:00:04 +08:00
CB-9782 Implements PlatformApi contract for Android platform.
This closes #226
This commit is contained in:
+1
@@ -0,0 +1 @@
|
||||
node_modules
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
language: node_js
|
||||
|
||||
node_js:
|
||||
- 0.6
|
||||
|
||||
script: make test
|
||||
|
||||
notifications:
|
||||
email:
|
||||
- tomaz+travisci@tomaz.me
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
elementtree v0.1.6 (in development)
|
||||
|
||||
* Add support for CData elements. (#14)
|
||||
[hermannpencole]
|
||||
|
||||
elementtree v0.1.5 - 2012-11-14
|
||||
|
||||
* Fix a bug in the find() and findtext() method which could manifest itself
|
||||
under some conditions.
|
||||
[metagriffin]
|
||||
|
||||
elementtree v0.1.4 - 2012-10-15
|
||||
|
||||
* Allow user to use namespaced attributes when using find* functions.
|
||||
[Andrew Lunny]
|
||||
|
||||
elementtree v0.1.3 - 2012-09-21
|
||||
|
||||
* Improve the output of text content in the tags (strip unnecessary line break
|
||||
characters).
|
||||
|
||||
[Darryl Pogue]
|
||||
|
||||
elementtree v0.1.2 - 2012-09-04
|
||||
|
||||
* Allow user to pass 'indent' option to ElementTree.write method. If this
|
||||
option is specified (e.g. {'indent': 4}). XML will be pretty printed.
|
||||
[Darryl Pogue, Tomaz Muraus]
|
||||
|
||||
* Bump sax dependency version.
|
||||
|
||||
elementtree v0.1.1 - 2011-09-23
|
||||
|
||||
* Improve special character escaping.
|
||||
[Ryan Phillips]
|
||||
|
||||
elementtree v0.1.0 - 2011-09-05
|
||||
|
||||
* Initial release.
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
TESTS := \
|
||||
tests/test-simple.js
|
||||
|
||||
|
||||
|
||||
PATH := ./node_modules/.bin:$(PATH)
|
||||
|
||||
WHISKEY := $(shell bash -c 'PATH=$(PATH) type -p whiskey')
|
||||
|
||||
default: test
|
||||
|
||||
test:
|
||||
NODE_PATH=`pwd`/lib/ ${WHISKEY} --scope-leaks --sequential --real-time --tests "${TESTS}"
|
||||
|
||||
tap:
|
||||
NODE_PATH=`pwd`/lib/ ${WHISKEY} --test-reporter tap --sequential --real-time --tests "${TESTS}"
|
||||
|
||||
coverage:
|
||||
NODE_PATH=`pwd`/lib/ ${WHISKEY} --sequential --coverage --coverage-reporter html --coverage-dir coverage_html --tests "${TESTS}"
|
||||
|
||||
.PHONY: default test coverage tap scope
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
node-elementtree
|
||||
Copyright (c) 2011, Rackspace, Inc.
|
||||
|
||||
The ElementTree toolkit is Copyright (c) 1999-2007 by Fredrik Lundh
|
||||
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
node-elementtree
|
||||
====================
|
||||
|
||||
node-elementtree is a [Node.js](http://nodejs.org) XML parser and serializer based upon the [Python ElementTree v1.3](http://effbot.org/zone/element-index.htm) module.
|
||||
|
||||
Installation
|
||||
====================
|
||||
|
||||
$ npm install elementtree
|
||||
|
||||
Using the library
|
||||
====================
|
||||
|
||||
For the usage refer to the Python ElementTree library documentation - [http://effbot.org/zone/element-index.htm#usage](http://effbot.org/zone/element-index.htm#usage).
|
||||
|
||||
Supported XPath expressions in `find`, `findall` and `findtext` methods are listed on [http://effbot.org/zone/element-xpath.htm](http://effbot.org/zone/element-xpath.htm).
|
||||
|
||||
Example 1 – Creating An XML Document
|
||||
====================
|
||||
|
||||
This example shows how to build a valid XML document that can be published to
|
||||
Atom Hopper. Atom Hopper is used internally as a bridge from products all the
|
||||
way to collecting revenue, called “Usage.” MaaS and other products send similar
|
||||
events to it every time user performs an action on a resource
|
||||
(e.g. creates,updates or deletes). Below is an example of leveraging the API
|
||||
to create a new XML document.
|
||||
|
||||
```javascript
|
||||
var et = require('elementtree');
|
||||
var XML = et.XML;
|
||||
var ElementTree = et.ElementTree;
|
||||
var element = et.Element;
|
||||
var subElement = et.SubElement;
|
||||
|
||||
var date, root, tenantId, serviceName, eventType, usageId, dataCenter, region,
|
||||
checks, resourceId, category, startTime, resourceName, etree, xml;
|
||||
|
||||
date = new Date();
|
||||
|
||||
root = element('entry');
|
||||
root.set('xmlns', 'http://www.w3.org/2005/Atom');
|
||||
|
||||
tenantId = subElement(root, 'TenantId');
|
||||
tenantId.text = '12345';
|
||||
|
||||
serviceName = subElement(root, 'ServiceName');
|
||||
serviceName.text = 'MaaS';
|
||||
|
||||
resourceId = subElement(root, 'ResourceID');
|
||||
resourceId.text = 'enAAAA';
|
||||
|
||||
usageId = subElement(root, 'UsageID');
|
||||
usageId.text = '550e8400-e29b-41d4-a716-446655440000';
|
||||
|
||||
eventType = subElement(root, 'EventType');
|
||||
eventType.text = 'create';
|
||||
|
||||
category = subElement(root, 'category');
|
||||
category.set('term', 'monitoring.entity.create');
|
||||
|
||||
dataCenter = subElement(root, 'DataCenter');
|
||||
dataCenter.text = 'global';
|
||||
|
||||
region = subElement(root, 'Region');
|
||||
region.text = 'global';
|
||||
|
||||
startTime = subElement(root, 'StartTime');
|
||||
startTime.text = date;
|
||||
|
||||
resourceName = subElement(root, 'ResourceName');
|
||||
resourceName.text = 'entity';
|
||||
|
||||
etree = new ElementTree(root);
|
||||
xml = etree.write({'xml_declaration': false});
|
||||
console.log(xml);
|
||||
```
|
||||
|
||||
As you can see, both et.Element and et.SubElement are factory methods which
|
||||
return a new instance of Element and SubElement class, respectively.
|
||||
When you create a new element (tag) you can use set method to set an attribute.
|
||||
To set the tag value, assign a value to the .text attribute.
|
||||
|
||||
This example would output a document that looks like this:
|
||||
|
||||
```xml
|
||||
<entry xmlns="http://www.w3.org/2005/Atom">
|
||||
<TenantId>12345</TenantId>
|
||||
<ServiceName>MaaS</ServiceName>
|
||||
<ResourceID>enAAAA</ResourceID>
|
||||
<UsageID>550e8400-e29b-41d4-a716-446655440000</UsageID>
|
||||
<EventType>create</EventType>
|
||||
<category term="monitoring.entity.create"/>
|
||||
<DataCenter>global</DataCenter>
|
||||
<Region>global</Region>
|
||||
<StartTime>Sun Apr 29 2012 16:37:32 GMT-0700 (PDT)</StartTime>
|
||||
<ResourceName>entity</ResourceName>
|
||||
</entry>
|
||||
```
|
||||
|
||||
Example 2 – Parsing An XML Document
|
||||
====================
|
||||
|
||||
This example shows how to parse an XML document and use simple XPath selectors.
|
||||
For demonstration purposes, we will use the XML document located at
|
||||
https://gist.github.com/2554343.
|
||||
|
||||
Behind the scenes, node-elementtree uses Isaac’s sax library for parsing XML,
|
||||
but the library has a concept of “parsers,” which means it’s pretty simple to
|
||||
add support for a different parser.
|
||||
|
||||
```javascript
|
||||
var fs = require('fs');
|
||||
|
||||
var et = require('elementtree');
|
||||
|
||||
var XML = et.XML;
|
||||
var ElementTree = et.ElementTree;
|
||||
var element = et.Element;
|
||||
var subElement = et.SubElement;
|
||||
|
||||
var data, etree;
|
||||
|
||||
data = fs.readFileSync('document.xml').toString();
|
||||
etree = et.parse(data);
|
||||
|
||||
console.log(etree.findall('./entry/TenantId').length); // 2
|
||||
console.log(etree.findtext('./entry/ServiceName')); // MaaS
|
||||
console.log(etree.findall('./entry/category')[0].get('term')); // monitoring.entity.create
|
||||
console.log(etree.findall('*/category/[@term="monitoring.entity.update"]').length); // 1
|
||||
```
|
||||
|
||||
Build status
|
||||
====================
|
||||
|
||||
[](http://travis-ci.org/racker/node-elementtree)
|
||||
|
||||
|
||||
License
|
||||
====================
|
||||
|
||||
node-elementtree is distributed under the [Apache license](http://www.apache.org/licenses/LICENSE-2.0.html).
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2011 Rackspace
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
var DEFAULT_PARSER = 'sax';
|
||||
|
||||
exports.DEFAULT_PARSER = DEFAULT_PARSER;
|
||||
+343
@@ -0,0 +1,343 @@
|
||||
/**
|
||||
* Copyright 2011 Rackspace
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
var sprintf = require('./sprintf').sprintf;
|
||||
|
||||
var utils = require('./utils');
|
||||
var SyntaxError = require('./errors').SyntaxError;
|
||||
|
||||
var _cache = {};
|
||||
|
||||
var RE = new RegExp(
|
||||
"(" +
|
||||
"'[^']*'|\"[^\"]*\"|" +
|
||||
"::|" +
|
||||
"//?|" +
|
||||
"\\.\\.|" +
|
||||
"\\(\\)|" +
|
||||
"[/.*:\\[\\]\\(\\)@=])|" +
|
||||
"((?:\\{[^}]+\\})?[^/\\[\\]\\(\\)@=\\s]+)|" +
|
||||
"\\s+", 'g'
|
||||
);
|
||||
|
||||
var xpath_tokenizer = utils.findall.bind(null, RE);
|
||||
|
||||
function prepare_tag(next, token) {
|
||||
var tag = token[0];
|
||||
|
||||
function select(context, result) {
|
||||
var i, len, elem, rv = [];
|
||||
|
||||
for (i = 0, len = result.length; i < len; i++) {
|
||||
elem = result[i];
|
||||
elem._children.forEach(function(e) {
|
||||
if (e.tag === tag) {
|
||||
rv.push(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
return select;
|
||||
}
|
||||
|
||||
function prepare_star(next, token) {
|
||||
function select(context, result) {
|
||||
var i, len, elem, rv = [];
|
||||
|
||||
for (i = 0, len = result.length; i < len; i++) {
|
||||
elem = result[i];
|
||||
elem._children.forEach(function(e) {
|
||||
rv.push(e);
|
||||
});
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
return select;
|
||||
}
|
||||
|
||||
function prepare_dot(next, token) {
|
||||
function select(context, result) {
|
||||
var i, len, elem, rv = [];
|
||||
|
||||
for (i = 0, len = result.length; i < len; i++) {
|
||||
elem = result[i];
|
||||
rv.push(elem);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
return select;
|
||||
}
|
||||
|
||||
function prepare_iter(next, token) {
|
||||
var tag;
|
||||
token = next();
|
||||
|
||||
if (token[1] === '*') {
|
||||
tag = '*';
|
||||
}
|
||||
else if (!token[1]) {
|
||||
tag = token[0] || '';
|
||||
}
|
||||
else {
|
||||
throw new SyntaxError(token);
|
||||
}
|
||||
|
||||
function select(context, result) {
|
||||
var i, len, elem, rv = [];
|
||||
|
||||
for (i = 0, len = result.length; i < len; i++) {
|
||||
elem = result[i];
|
||||
elem.iter(tag, function(e) {
|
||||
if (e !== elem) {
|
||||
rv.push(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
return select;
|
||||
}
|
||||
|
||||
function prepare_dot_dot(next, token) {
|
||||
function select(context, result) {
|
||||
var i, len, elem, rv = [], parent_map = context.parent_map;
|
||||
|
||||
if (!parent_map) {
|
||||
context.parent_map = parent_map = {};
|
||||
|
||||
context.root.iter(null, function(p) {
|
||||
p._children.forEach(function(e) {
|
||||
parent_map[e] = p;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
for (i = 0, len = result.length; i < len; i++) {
|
||||
elem = result[i];
|
||||
|
||||
if (parent_map.hasOwnProperty(elem)) {
|
||||
rv.push(parent_map[elem]);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
return select;
|
||||
}
|
||||
|
||||
|
||||
function prepare_predicate(next, token) {
|
||||
var tag, key, value, select;
|
||||
token = next();
|
||||
|
||||
if (token[1] === '@') {
|
||||
// attribute
|
||||
token = next();
|
||||
|
||||
if (token[1]) {
|
||||
throw new SyntaxError(token, 'Invalid attribute predicate');
|
||||
}
|
||||
|
||||
key = token[0];
|
||||
token = next();
|
||||
|
||||
if (token[1] === ']') {
|
||||
select = function(context, result) {
|
||||
var i, len, elem, rv = [];
|
||||
|
||||
for (i = 0, len = result.length; i < len; i++) {
|
||||
elem = result[i];
|
||||
|
||||
if (elem.get(key)) {
|
||||
rv.push(elem);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
};
|
||||
}
|
||||
else if (token[1] === '=') {
|
||||
value = next()[1];
|
||||
|
||||
if (value[0] === '"' || value[value.length - 1] === '\'') {
|
||||
value = value.slice(1, value.length - 1);
|
||||
}
|
||||
else {
|
||||
throw new SyntaxError(token, 'Ivalid comparison target');
|
||||
}
|
||||
|
||||
token = next();
|
||||
select = function(context, result) {
|
||||
var i, len, elem, rv = [];
|
||||
|
||||
for (i = 0, len = result.length; i < len; i++) {
|
||||
elem = result[i];
|
||||
|
||||
if (elem.get(key) === value) {
|
||||
rv.push(elem);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
};
|
||||
}
|
||||
|
||||
if (token[1] !== ']') {
|
||||
throw new SyntaxError(token, 'Invalid attribute predicate');
|
||||
}
|
||||
}
|
||||
else if (!token[1]) {
|
||||
tag = token[0] || '';
|
||||
token = next();
|
||||
|
||||
if (token[1] !== ']') {
|
||||
throw new SyntaxError(token, 'Invalid node predicate');
|
||||
}
|
||||
|
||||
select = function(context, result) {
|
||||
var i, len, elem, rv = [];
|
||||
|
||||
for (i = 0, len = result.length; i < len; i++) {
|
||||
elem = result[i];
|
||||
|
||||
if (elem.find(tag)) {
|
||||
rv.push(elem);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
};
|
||||
}
|
||||
else {
|
||||
throw new SyntaxError(null, 'Invalid predicate');
|
||||
}
|
||||
|
||||
return select;
|
||||
}
|
||||
|
||||
|
||||
|
||||
var ops = {
|
||||
"": prepare_tag,
|
||||
"*": prepare_star,
|
||||
".": prepare_dot,
|
||||
"..": prepare_dot_dot,
|
||||
"//": prepare_iter,
|
||||
"[": prepare_predicate,
|
||||
};
|
||||
|
||||
function _SelectorContext(root) {
|
||||
this.parent_map = null;
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
function findall(elem, path) {
|
||||
var selector, result, i, len, token, value, select, context;
|
||||
|
||||
if (_cache.hasOwnProperty(path)) {
|
||||
selector = _cache[path];
|
||||
}
|
||||
else {
|
||||
// TODO: Use smarter cache purging approach
|
||||
if (Object.keys(_cache).length > 100) {
|
||||
_cache = {};
|
||||
}
|
||||
|
||||
if (path.charAt(0) === '/') {
|
||||
throw new SyntaxError(null, 'Cannot use absolute path on element');
|
||||
}
|
||||
|
||||
result = xpath_tokenizer(path);
|
||||
selector = [];
|
||||
|
||||
function getToken() {
|
||||
return result.shift();
|
||||
}
|
||||
|
||||
token = getToken();
|
||||
while (true) {
|
||||
var c = token[1] || '';
|
||||
value = ops[c](getToken, token);
|
||||
|
||||
if (!value) {
|
||||
throw new SyntaxError(null, sprintf('Invalid path: %s', path));
|
||||
}
|
||||
|
||||
selector.push(value);
|
||||
token = getToken();
|
||||
|
||||
if (!token) {
|
||||
break;
|
||||
}
|
||||
else if (token[1] === '/') {
|
||||
token = getToken();
|
||||
}
|
||||
|
||||
if (!token) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_cache[path] = selector;
|
||||
}
|
||||
|
||||
// Execute slector pattern
|
||||
result = [elem];
|
||||
context = new _SelectorContext(elem);
|
||||
|
||||
for (i = 0, len = selector.length; i < len; i++) {
|
||||
select = selector[i];
|
||||
result = select(context, result);
|
||||
}
|
||||
|
||||
return result || [];
|
||||
}
|
||||
|
||||
function find(element, path) {
|
||||
var resultElements = findall(element, path);
|
||||
|
||||
if (resultElements && resultElements.length > 0) {
|
||||
return resultElements[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function findtext(element, path, defvalue) {
|
||||
var resultElements = findall(element, path);
|
||||
|
||||
if (resultElements && resultElements.length > 0) {
|
||||
return resultElements[0].text;
|
||||
}
|
||||
|
||||
return defvalue;
|
||||
}
|
||||
|
||||
|
||||
exports.find = find;
|
||||
exports.findall = findall;
|
||||
exports.findtext = findtext;
|
||||
+611
@@ -0,0 +1,611 @@
|
||||
/**
|
||||
* Copyright 2011 Rackspace
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
var sprintf = require('./sprintf').sprintf;
|
||||
|
||||
var utils = require('./utils');
|
||||
var ElementPath = require('./elementpath');
|
||||
var TreeBuilder = require('./treebuilder').TreeBuilder;
|
||||
var get_parser = require('./parser').get_parser;
|
||||
var constants = require('./constants');
|
||||
|
||||
var element_ids = 0;
|
||||
|
||||
function Element(tag, attrib)
|
||||
{
|
||||
this._id = element_ids++;
|
||||
this.tag = tag;
|
||||
this.attrib = {};
|
||||
this.text = null;
|
||||
this.tail = null;
|
||||
this._children = [];
|
||||
|
||||
if (attrib) {
|
||||
this.attrib = utils.merge(this.attrib, attrib);
|
||||
}
|
||||
}
|
||||
|
||||
Element.prototype.toString = function()
|
||||
{
|
||||
return sprintf("<Element %s at %s>", this.tag, this._id);
|
||||
};
|
||||
|
||||
Element.prototype.makeelement = function(tag, attrib)
|
||||
{
|
||||
return new Element(tag, attrib);
|
||||
};
|
||||
|
||||
Element.prototype.len = function()
|
||||
{
|
||||
return this._children.length;
|
||||
};
|
||||
|
||||
Element.prototype.getItem = function(index)
|
||||
{
|
||||
return this._children[index];
|
||||
};
|
||||
|
||||
Element.prototype.setItem = function(index, element)
|
||||
{
|
||||
this._children[index] = element;
|
||||
};
|
||||
|
||||
Element.prototype.delItem = function(index)
|
||||
{
|
||||
this._children.splice(index, 1);
|
||||
};
|
||||
|
||||
Element.prototype.getSlice = function(start, stop)
|
||||
{
|
||||
return this._children.slice(start, stop);
|
||||
};
|
||||
|
||||
Element.prototype.setSlice = function(start, stop, elements)
|
||||
{
|
||||
var i;
|
||||
var k = 0;
|
||||
for (i = start; i < stop; i++, k++) {
|
||||
this._children[i] = elements[k];
|
||||
}
|
||||
};
|
||||
|
||||
Element.prototype.delSlice = function(start, stop)
|
||||
{
|
||||
this._children.splice(start, stop - start);
|
||||
};
|
||||
|
||||
Element.prototype.append = function(element)
|
||||
{
|
||||
this._children.push(element);
|
||||
};
|
||||
|
||||
Element.prototype.extend = function(elements)
|
||||
{
|
||||
this._children.concat(elements);
|
||||
};
|
||||
|
||||
Element.prototype.insert = function(index, element)
|
||||
{
|
||||
this._children[index] = element;
|
||||
};
|
||||
|
||||
Element.prototype.remove = function(element)
|
||||
{
|
||||
this._children = this._children.filter(function(e) {
|
||||
/* TODO: is this the right way to do this? */
|
||||
if (e._id === element._id) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
Element.prototype.getchildren = function() {
|
||||
return this._children;
|
||||
};
|
||||
|
||||
Element.prototype.find = function(path)
|
||||
{
|
||||
return ElementPath.find(this, path);
|
||||
};
|
||||
|
||||
Element.prototype.findtext = function(path, defvalue)
|
||||
{
|
||||
return ElementPath.findtext(this, path, defvalue);
|
||||
};
|
||||
|
||||
Element.prototype.findall = function(path, defvalue)
|
||||
{
|
||||
return ElementPath.findall(this, path, defvalue);
|
||||
};
|
||||
|
||||
Element.prototype.clear = function()
|
||||
{
|
||||
this.attrib = {};
|
||||
this._children = [];
|
||||
this.text = null;
|
||||
this.tail = null;
|
||||
};
|
||||
|
||||
Element.prototype.get = function(key, defvalue)
|
||||
{
|
||||
if (this.attrib[key] !== undefined) {
|
||||
return this.attrib[key];
|
||||
}
|
||||
else {
|
||||
return defvalue;
|
||||
}
|
||||
};
|
||||
|
||||
Element.prototype.set = function(key, value)
|
||||
{
|
||||
this.attrib[key] = value;
|
||||
};
|
||||
|
||||
Element.prototype.keys = function()
|
||||
{
|
||||
return Object.keys(this.attrib);
|
||||
};
|
||||
|
||||
Element.prototype.items = function()
|
||||
{
|
||||
return utils.items(this.attrib);
|
||||
};
|
||||
|
||||
/*
|
||||
* In python this uses a generator, but in v8 we don't have em,
|
||||
* so we use a callback instead.
|
||||
**/
|
||||
Element.prototype.iter = function(tag, callback)
|
||||
{
|
||||
var self = this;
|
||||
var i, child;
|
||||
|
||||
if (tag === "*") {
|
||||
tag = null;
|
||||
}
|
||||
|
||||
if (tag === null || this.tag === tag) {
|
||||
callback(self);
|
||||
}
|
||||
|
||||
for (i = 0; i < this._children.length; i++) {
|
||||
child = this._children[i];
|
||||
child.iter(tag, function(e) {
|
||||
callback(e);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Element.prototype.itertext = function(callback)
|
||||
{
|
||||
this.iter(null, function(e) {
|
||||
if (e.text) {
|
||||
callback(e.text);
|
||||
}
|
||||
|
||||
if (e.tail) {
|
||||
callback(e.tail);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
function SubElement(parent, tag, attrib) {
|
||||
var element = parent.makeelement(tag, attrib);
|
||||
parent.append(element);
|
||||
return element;
|
||||
}
|
||||
|
||||
function Comment(text) {
|
||||
var element = new Element(Comment);
|
||||
if (text) {
|
||||
element.text = text;
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
function CData(text) {
|
||||
var element = new Element(CData);
|
||||
if (text) {
|
||||
element.text = text;
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
function ProcessingInstruction(target, text)
|
||||
{
|
||||
var element = new Element(ProcessingInstruction);
|
||||
element.text = target;
|
||||
if (text) {
|
||||
element.text = element.text + " " + text;
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
function QName(text_or_uri, tag)
|
||||
{
|
||||
if (tag) {
|
||||
text_or_uri = sprintf("{%s}%s", text_or_uri, tag);
|
||||
}
|
||||
this.text = text_or_uri;
|
||||
}
|
||||
|
||||
QName.prototype.toString = function() {
|
||||
return this.text;
|
||||
};
|
||||
|
||||
function ElementTree(element)
|
||||
{
|
||||
this._root = element;
|
||||
}
|
||||
|
||||
ElementTree.prototype.getroot = function() {
|
||||
return this._root;
|
||||
};
|
||||
|
||||
ElementTree.prototype._setroot = function(element) {
|
||||
this._root = element;
|
||||
};
|
||||
|
||||
ElementTree.prototype.parse = function(source, parser) {
|
||||
if (!parser) {
|
||||
parser = get_parser(constants.DEFAULT_PARSER);
|
||||
parser = new parser.XMLParser(new TreeBuilder());
|
||||
}
|
||||
|
||||
parser.feed(source);
|
||||
this._root = parser.close();
|
||||
return this._root;
|
||||
};
|
||||
|
||||
ElementTree.prototype.iter = function(tag, callback) {
|
||||
this._root.iter(tag, callback);
|
||||
};
|
||||
|
||||
ElementTree.prototype.find = function(path) {
|
||||
return this._root.find(path);
|
||||
};
|
||||
|
||||
ElementTree.prototype.findtext = function(path, defvalue) {
|
||||
return this._root.findtext(path, defvalue);
|
||||
};
|
||||
|
||||
ElementTree.prototype.findall = function(path) {
|
||||
return this._root.findall(path);
|
||||
};
|
||||
|
||||
/**
|
||||
* Unlike ElementTree, we don't write to a file, we return you a string.
|
||||
*/
|
||||
ElementTree.prototype.write = function(options) {
|
||||
var sb = [];
|
||||
options = utils.merge({
|
||||
encoding: 'utf-8',
|
||||
xml_declaration: null,
|
||||
default_namespace: null,
|
||||
method: 'xml'}, options);
|
||||
|
||||
if (options.xml_declaration !== false) {
|
||||
sb.push("<?xml version='1.0' encoding='"+options.encoding +"'?>\n");
|
||||
}
|
||||
|
||||
if (options.method === "text") {
|
||||
_serialize_text(sb, self._root, encoding);
|
||||
}
|
||||
else {
|
||||
var qnames, namespaces, indent, indent_string;
|
||||
var x = _namespaces(this._root, options.encoding, options.default_namespace);
|
||||
qnames = x[0];
|
||||
namespaces = x[1];
|
||||
|
||||
if (options.hasOwnProperty('indent')) {
|
||||
indent = 0;
|
||||
indent_string = new Array(options.indent + 1).join(' ');
|
||||
}
|
||||
else {
|
||||
indent = false;
|
||||
}
|
||||
|
||||
if (options.method === "xml") {
|
||||
_serialize_xml(function(data) {
|
||||
sb.push(data);
|
||||
}, this._root, options.encoding, qnames, namespaces, indent, indent_string);
|
||||
}
|
||||
else {
|
||||
/* TODO: html */
|
||||
throw new Error("unknown serialization method "+ options.method);
|
||||
}
|
||||
}
|
||||
|
||||
return sb.join("");
|
||||
};
|
||||
|
||||
var _namespace_map = {
|
||||
/* "well-known" namespace prefixes */
|
||||
"http://www.w3.org/XML/1998/namespace": "xml",
|
||||
"http://www.w3.org/1999/xhtml": "html",
|
||||
"http://www.w3.org/1999/02/22-rdf-syntax-ns#": "rdf",
|
||||
"http://schemas.xmlsoap.org/wsdl/": "wsdl",
|
||||
/* xml schema */
|
||||
"http://www.w3.org/2001/XMLSchema": "xs",
|
||||
"http://www.w3.org/2001/XMLSchema-instance": "xsi",
|
||||
/* dublic core */
|
||||
"http://purl.org/dc/elements/1.1/": "dc",
|
||||
};
|
||||
|
||||
function register_namespace(prefix, uri) {
|
||||
if (/ns\d+$/.test(prefix)) {
|
||||
throw new Error('Prefix format reserved for internal use');
|
||||
}
|
||||
|
||||
if (_namespace_map.hasOwnProperty(uri) && _namespace_map[uri] === prefix) {
|
||||
delete _namespace_map[uri];
|
||||
}
|
||||
|
||||
_namespace_map[uri] = prefix;
|
||||
}
|
||||
|
||||
|
||||
function _escape(text, encoding, isAttribute, isText) {
|
||||
if (text) {
|
||||
text = text.toString();
|
||||
text = text.replace(/&/g, '&');
|
||||
text = text.replace(/</g, '<');
|
||||
text = text.replace(/>/g, '>');
|
||||
if (!isText) {
|
||||
text = text.replace(/\n/g, '
');
|
||||
text = text.replace(/\r/g, '
');
|
||||
}
|
||||
if (isAttribute) {
|
||||
text = text.replace(/"/g, '"');
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
/* TODO: benchmark single regex */
|
||||
function _escape_attrib(text, encoding) {
|
||||
return _escape(text, encoding, true);
|
||||
}
|
||||
|
||||
function _escape_cdata(text, encoding) {
|
||||
return _escape(text, encoding, false);
|
||||
}
|
||||
|
||||
function _escape_text(text, encoding) {
|
||||
return _escape(text, encoding, false, true);
|
||||
}
|
||||
|
||||
function _namespaces(elem, encoding, default_namespace) {
|
||||
var qnames = {};
|
||||
var namespaces = {};
|
||||
|
||||
if (default_namespace) {
|
||||
namespaces[default_namespace] = "";
|
||||
}
|
||||
|
||||
function encode(text) {
|
||||
return text;
|
||||
}
|
||||
|
||||
function add_qname(qname) {
|
||||
if (qname[0] === "{") {
|
||||
var tmp = qname.substring(1).split("}", 2);
|
||||
var uri = tmp[0];
|
||||
var tag = tmp[1];
|
||||
var prefix = namespaces[uri];
|
||||
|
||||
if (prefix === undefined) {
|
||||
prefix = _namespace_map[uri];
|
||||
if (prefix === undefined) {
|
||||
prefix = "ns" + Object.keys(namespaces).length;
|
||||
}
|
||||
if (prefix !== "xml") {
|
||||
namespaces[uri] = prefix;
|
||||
}
|
||||
}
|
||||
|
||||
if (prefix) {
|
||||
qnames[qname] = sprintf("%s:%s", prefix, tag);
|
||||
}
|
||||
else {
|
||||
qnames[qname] = tag;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (default_namespace) {
|
||||
throw new Error('cannot use non-qualified names with default_namespace option');
|
||||
}
|
||||
|
||||
qnames[qname] = qname;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
elem.iter(null, function(e) {
|
||||
var i;
|
||||
var tag = e.tag;
|
||||
var text = e.text;
|
||||
var items = e.items();
|
||||
|
||||
if (tag instanceof QName && qnames[tag.text] === undefined) {
|
||||
add_qname(tag.text);
|
||||
}
|
||||
else if (typeof(tag) === "string") {
|
||||
add_qname(tag);
|
||||
}
|
||||
else if (tag !== null && tag !== Comment && tag !== CData && tag !== ProcessingInstruction) {
|
||||
throw new Error('Invalid tag type for serialization: '+ tag);
|
||||
}
|
||||
|
||||
if (text instanceof QName && qnames[text.text] === undefined) {
|
||||
add_qname(text.text);
|
||||
}
|
||||
|
||||
items.forEach(function(item) {
|
||||
var key = item[0],
|
||||
value = item[1];
|
||||
if (key instanceof QName) {
|
||||
key = key.text;
|
||||
}
|
||||
|
||||
if (qnames[key] === undefined) {
|
||||
add_qname(key);
|
||||
}
|
||||
|
||||
if (value instanceof QName && qnames[value.text] === undefined) {
|
||||
add_qname(value.text);
|
||||
}
|
||||
});
|
||||
});
|
||||
return [qnames, namespaces];
|
||||
}
|
||||
|
||||
function _serialize_xml(write, elem, encoding, qnames, namespaces, indent, indent_string) {
|
||||
var tag = elem.tag;
|
||||
var text = elem.text;
|
||||
var items;
|
||||
var i;
|
||||
|
||||
var newlines = indent || (indent === 0);
|
||||
write(Array(indent + 1).join(indent_string));
|
||||
|
||||
if (tag === Comment) {
|
||||
write(sprintf("<!--%s-->", _escape_cdata(text, encoding)));
|
||||
}
|
||||
else if (tag === ProcessingInstruction) {
|
||||
write(sprintf("<?%s?>", _escape_cdata(text, encoding)));
|
||||
}
|
||||
else if (tag === CData) {
|
||||
text = text || '';
|
||||
write(sprintf("<![CDATA[%s]]>", text));
|
||||
}
|
||||
else {
|
||||
tag = qnames[tag];
|
||||
if (tag === undefined) {
|
||||
if (text) {
|
||||
write(_escape_text(text, encoding));
|
||||
}
|
||||
elem.iter(function(e) {
|
||||
_serialize_xml(write, e, encoding, qnames, null, newlines ? indent + 1 : false, indent_string);
|
||||
});
|
||||
}
|
||||
else {
|
||||
write("<" + tag);
|
||||
items = elem.items();
|
||||
|
||||
if (items || namespaces) {
|
||||
items.sort(); // lexical order
|
||||
|
||||
items.forEach(function(item) {
|
||||
var k = item[0],
|
||||
v = item[1];
|
||||
|
||||
if (k instanceof QName) {
|
||||
k = k.text;
|
||||
}
|
||||
|
||||
if (v instanceof QName) {
|
||||
v = qnames[v.text];
|
||||
}
|
||||
else {
|
||||
v = _escape_attrib(v, encoding);
|
||||
}
|
||||
write(sprintf(" %s=\"%s\"", qnames[k], v));
|
||||
});
|
||||
|
||||
if (namespaces) {
|
||||
items = utils.items(namespaces);
|
||||
items.sort(function(a, b) { return a[1] < b[1]; });
|
||||
|
||||
items.forEach(function(item) {
|
||||
var k = item[1],
|
||||
v = item[0];
|
||||
|
||||
if (k) {
|
||||
k = ':' + k;
|
||||
}
|
||||
|
||||
write(sprintf(" xmlns%s=\"%s\"", k, _escape_attrib(v, encoding)));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (text || elem.len()) {
|
||||
if (text && text.toString().match(/^\s*$/)) {
|
||||
text = null;
|
||||
}
|
||||
|
||||
write(">");
|
||||
if (!text && newlines) {
|
||||
write("\n");
|
||||
}
|
||||
|
||||
if (text) {
|
||||
write(_escape_text(text, encoding));
|
||||
}
|
||||
elem._children.forEach(function(e) {
|
||||
_serialize_xml(write, e, encoding, qnames, null, newlines ? indent + 1 : false, indent_string);
|
||||
});
|
||||
|
||||
if (!text && indent) {
|
||||
write(Array(indent + 1).join(indent_string));
|
||||
}
|
||||
write("</" + tag + ">");
|
||||
}
|
||||
else {
|
||||
write(" />");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (newlines) {
|
||||
write("\n");
|
||||
}
|
||||
}
|
||||
|
||||
function parse(source, parser) {
|
||||
var tree = new ElementTree();
|
||||
tree.parse(source, parser);
|
||||
return tree;
|
||||
}
|
||||
|
||||
function tostring(element, options) {
|
||||
return new ElementTree(element).write(options);
|
||||
}
|
||||
|
||||
exports.PI = ProcessingInstruction;
|
||||
exports.Comment = Comment;
|
||||
exports.CData = CData;
|
||||
exports.ProcessingInstruction = ProcessingInstruction;
|
||||
exports.SubElement = SubElement;
|
||||
exports.QName = QName;
|
||||
exports.ElementTree = ElementTree;
|
||||
exports.ElementPath = ElementPath;
|
||||
exports.Element = function(tag, attrib) {
|
||||
return new Element(tag, attrib);
|
||||
};
|
||||
|
||||
exports.XML = function(data) {
|
||||
var et = new ElementTree();
|
||||
return et.parse(data);
|
||||
};
|
||||
|
||||
exports.parse = parse;
|
||||
exports.register_namespace = register_namespace;
|
||||
exports.tostring = tostring;
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright 2011 Rackspace
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
var util = require('util');
|
||||
|
||||
var sprintf = require('./sprintf').sprintf;
|
||||
|
||||
function SyntaxError(token, msg) {
|
||||
msg = msg || sprintf('Syntax Error at token %s', token.toString());
|
||||
this.token = token;
|
||||
this.message = msg;
|
||||
Error.call(this, msg);
|
||||
}
|
||||
|
||||
util.inherits(SyntaxError, Error);
|
||||
|
||||
exports.SyntaxError = SyntaxError;
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2011 Rackspace
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
/* TODO: support node-expat C++ module optionally */
|
||||
|
||||
var util = require('util');
|
||||
var parsers = require('./parsers/index');
|
||||
|
||||
function get_parser(name) {
|
||||
if (name === 'sax') {
|
||||
return parsers.sax;
|
||||
}
|
||||
else {
|
||||
throw new Error('Invalid parser: ' + name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
exports.get_parser = get_parser;
|
||||
+1
@@ -0,0 +1 @@
|
||||
exports.sax = require('./sax');
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
var util = require('util');
|
||||
|
||||
var sax = require('sax');
|
||||
|
||||
var TreeBuilder = require('./../treebuilder').TreeBuilder;
|
||||
|
||||
function XMLParser(target) {
|
||||
this.parser = sax.parser(true);
|
||||
|
||||
this.target = (target) ? target : new TreeBuilder();
|
||||
|
||||
this.parser.onopentag = this._handleOpenTag.bind(this);
|
||||
this.parser.ontext = this._handleText.bind(this);
|
||||
this.parser.oncdata = this._handleCdata.bind(this);
|
||||
this.parser.ondoctype = this._handleDoctype.bind(this);
|
||||
this.parser.oncomment = this._handleComment.bind(this);
|
||||
this.parser.onclosetag = this._handleCloseTag.bind(this);
|
||||
this.parser.onerror = this._handleError.bind(this);
|
||||
}
|
||||
|
||||
XMLParser.prototype._handleOpenTag = function(tag) {
|
||||
this.target.start(tag.name, tag.attributes);
|
||||
};
|
||||
|
||||
XMLParser.prototype._handleText = function(text) {
|
||||
this.target.data(text);
|
||||
};
|
||||
|
||||
XMLParser.prototype._handleCdata = function(text) {
|
||||
this.target.data(text);
|
||||
};
|
||||
|
||||
XMLParser.prototype._handleDoctype = function(text) {
|
||||
};
|
||||
|
||||
XMLParser.prototype._handleComment = function(comment) {
|
||||
};
|
||||
|
||||
XMLParser.prototype._handleCloseTag = function(tag) {
|
||||
this.target.end(tag);
|
||||
};
|
||||
|
||||
XMLParser.prototype._handleError = function(err) {
|
||||
throw err;
|
||||
};
|
||||
|
||||
XMLParser.prototype.feed = function(chunk) {
|
||||
this.parser.write(chunk);
|
||||
};
|
||||
|
||||
XMLParser.prototype.close = function() {
|
||||
this.parser.close();
|
||||
return this.target.close();
|
||||
};
|
||||
|
||||
exports.XMLParser = XMLParser;
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2011 Rackspace
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
var cache = {};
|
||||
|
||||
|
||||
// Do any others need escaping?
|
||||
var TO_ESCAPE = {
|
||||
'\'': '\\\'',
|
||||
'\n': '\\n'
|
||||
};
|
||||
|
||||
|
||||
function populate(formatter) {
|
||||
var i, type,
|
||||
key = formatter,
|
||||
prev = 0,
|
||||
arg = 1,
|
||||
builder = 'return \'';
|
||||
|
||||
for (i = 0; i < formatter.length; i++) {
|
||||
if (formatter[i] === '%') {
|
||||
type = formatter[i + 1];
|
||||
|
||||
switch (type) {
|
||||
case 's':
|
||||
builder += formatter.slice(prev, i) + '\' + arguments[' + arg + '] + \'';
|
||||
prev = i + 2;
|
||||
arg++;
|
||||
break;
|
||||
case 'j':
|
||||
builder += formatter.slice(prev, i) + '\' + JSON.stringify(arguments[' + arg + ']) + \'';
|
||||
prev = i + 2;
|
||||
arg++;
|
||||
break;
|
||||
case '%':
|
||||
builder += formatter.slice(prev, i + 1);
|
||||
prev = i + 2;
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
} else if (TO_ESCAPE[formatter[i]]) {
|
||||
builder += formatter.slice(prev, i) + TO_ESCAPE[formatter[i]];
|
||||
prev = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
builder += formatter.slice(prev) + '\';';
|
||||
cache[key] = new Function(builder);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A fast version of sprintf(), which currently only supports the %s and %j.
|
||||
* This caches a formatting function for each format string that is used, so
|
||||
* you should only use this sprintf() will be called many times with a single
|
||||
* format string and a limited number of format strings will ever be used (in
|
||||
* general this means that format strings should be string literals).
|
||||
*
|
||||
* @param {String} formatter A format string.
|
||||
* @param {...String} var_args Values that will be formatted by %s and %j.
|
||||
* @return {String} The formatted output.
|
||||
*/
|
||||
exports.sprintf = function(formatter, var_args) {
|
||||
if (!cache[formatter]) {
|
||||
populate(formatter);
|
||||
}
|
||||
|
||||
return cache[formatter].apply(null, arguments);
|
||||
};
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
function TreeBuilder(element_factory) {
|
||||
this._data = [];
|
||||
this._elem = [];
|
||||
this._last = null;
|
||||
this._tail = null;
|
||||
if (!element_factory) {
|
||||
/* evil circular dep */
|
||||
element_factory = require('./elementtree').Element;
|
||||
}
|
||||
this._factory = element_factory;
|
||||
}
|
||||
|
||||
TreeBuilder.prototype.close = function() {
|
||||
return this._last;
|
||||
};
|
||||
|
||||
TreeBuilder.prototype._flush = function() {
|
||||
if (this._data) {
|
||||
if (this._last !== null) {
|
||||
var text = this._data.join("");
|
||||
if (this._tail) {
|
||||
this._last.tail = text;
|
||||
}
|
||||
else {
|
||||
this._last.text = text;
|
||||
}
|
||||
}
|
||||
this._data = [];
|
||||
}
|
||||
};
|
||||
|
||||
TreeBuilder.prototype.data = function(data) {
|
||||
this._data.push(data);
|
||||
};
|
||||
|
||||
TreeBuilder.prototype.start = function(tag, attrs) {
|
||||
this._flush();
|
||||
var elem = this._factory(tag, attrs);
|
||||
this._last = elem;
|
||||
|
||||
if (this._elem.length) {
|
||||
this._elem[this._elem.length - 1].append(elem);
|
||||
}
|
||||
|
||||
this._elem.push(elem);
|
||||
|
||||
this._tail = null;
|
||||
};
|
||||
|
||||
TreeBuilder.prototype.end = function(tag) {
|
||||
this._flush();
|
||||
this._last = this._elem.pop();
|
||||
if (this._last.tag !== tag) {
|
||||
throw new Error("end tag mismatch");
|
||||
}
|
||||
this._tail = 1;
|
||||
return this._last;
|
||||
};
|
||||
|
||||
exports.TreeBuilder = TreeBuilder;
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Copyright 2011 Rackspace
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {Object} hash.
|
||||
* @param {Array} ignored.
|
||||
*/
|
||||
function items(hash, ignored) {
|
||||
ignored = ignored || null;
|
||||
var k, rv = [];
|
||||
|
||||
function is_ignored(key) {
|
||||
if (!ignored || ignored.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ignored.indexOf(key);
|
||||
}
|
||||
|
||||
for (k in hash) {
|
||||
if (hash.hasOwnProperty(k) && !(is_ignored(ignored))) {
|
||||
rv.push([k, hash[k]]);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
function findall(re, str) {
|
||||
var match, matches = [];
|
||||
|
||||
while ((match = re.exec(str))) {
|
||||
matches.push(match);
|
||||
}
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
function merge(a, b) {
|
||||
var c = {}, attrname;
|
||||
|
||||
for (attrname in a) {
|
||||
if (a.hasOwnProperty(attrname)) {
|
||||
c[attrname] = a[attrname];
|
||||
}
|
||||
}
|
||||
for (attrname in b) {
|
||||
if (b.hasOwnProperty(attrname)) {
|
||||
c[attrname] = b[attrname];
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
exports.items = items;
|
||||
exports.findall = findall;
|
||||
exports.merge = merge;
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
# contributors sorted by whether or not they're me.
|
||||
Isaac Z. Schlueter <i@izs.me>
|
||||
Stein Martin Hustad <stein@hustad.com>
|
||||
Mikeal Rogers <mikeal.rogers@gmail.com>
|
||||
Laurie Harper <laurie@holoweb.net>
|
||||
Jann Horn <jann@Jann-PC.fritz.box>
|
||||
Elijah Insua <tmpvar@gmail.com>
|
||||
Henry Rawas <henryr@schakra.com>
|
||||
Justin Makeig <jmpublic@makeig.com>
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
+213
@@ -0,0 +1,213 @@
|
||||
# sax js
|
||||
|
||||
A sax-style parser for XML and HTML.
|
||||
|
||||
Designed with [node](http://nodejs.org/) in mind, but should work fine in
|
||||
the browser or other CommonJS implementations.
|
||||
|
||||
## What This Is
|
||||
|
||||
* A very simple tool to parse through an XML string.
|
||||
* A stepping stone to a streaming HTML parser.
|
||||
* A handy way to deal with RSS and other mostly-ok-but-kinda-broken XML
|
||||
docs.
|
||||
|
||||
## What This Is (probably) Not
|
||||
|
||||
* An HTML Parser - That's a fine goal, but this isn't it. It's just
|
||||
XML.
|
||||
* A DOM Builder - You can use it to build an object model out of XML,
|
||||
but it doesn't do that out of the box.
|
||||
* XSLT - No DOM = no querying.
|
||||
* 100% Compliant with (some other SAX implementation) - Most SAX
|
||||
implementations are in Java and do a lot more than this does.
|
||||
* An XML Validator - It does a little validation when in strict mode, but
|
||||
not much.
|
||||
* A Schema-Aware XSD Thing - Schemas are an exercise in fetishistic
|
||||
masochism.
|
||||
* A DTD-aware Thing - Fetching DTDs is a much bigger job.
|
||||
|
||||
## Regarding `<!DOCTYPE`s and `<!ENTITY`s
|
||||
|
||||
The parser will handle the basic XML entities in text nodes and attribute
|
||||
values: `& < > ' "`. It's possible to define additional
|
||||
entities in XML by putting them in the DTD. This parser doesn't do anything
|
||||
with that. If you want to listen to the `ondoctype` event, and then fetch
|
||||
the doctypes, and read the entities and add them to `parser.ENTITIES`, then
|
||||
be my guest.
|
||||
|
||||
Unknown entities will fail in strict mode, and in loose mode, will pass
|
||||
through unmolested.
|
||||
|
||||
## Usage
|
||||
|
||||
var sax = require("./lib/sax"),
|
||||
strict = true, // set to false for html-mode
|
||||
parser = sax.parser(strict);
|
||||
|
||||
parser.onerror = function (e) {
|
||||
// an error happened.
|
||||
};
|
||||
parser.ontext = function (t) {
|
||||
// got some text. t is the string of text.
|
||||
};
|
||||
parser.onopentag = function (node) {
|
||||
// opened a tag. node has "name" and "attributes"
|
||||
};
|
||||
parser.onattribute = function (attr) {
|
||||
// an attribute. attr has "name" and "value"
|
||||
};
|
||||
parser.onend = function () {
|
||||
// parser stream is done, and ready to have more stuff written to it.
|
||||
};
|
||||
|
||||
parser.write('<xml>Hello, <who name="world">world</who>!</xml>').close();
|
||||
|
||||
// stream usage
|
||||
// takes the same options as the parser
|
||||
var saxStream = require("sax").createStream(strict, options)
|
||||
saxStream.on("error", function (e) {
|
||||
// unhandled errors will throw, since this is a proper node
|
||||
// event emitter.
|
||||
console.error("error!", e)
|
||||
// clear the error
|
||||
this._parser.error = null
|
||||
this._parser.resume()
|
||||
})
|
||||
saxStream.on("opentag", function (node) {
|
||||
// same object as above
|
||||
})
|
||||
// pipe is supported, and it's readable/writable
|
||||
// same chunks coming in also go out.
|
||||
fs.createReadStream("file.xml")
|
||||
.pipe(saxStream)
|
||||
.pipe(fs.createReadStream("file-copy.xml"))
|
||||
|
||||
|
||||
|
||||
## Arguments
|
||||
|
||||
Pass the following arguments to the parser function. All are optional.
|
||||
|
||||
`strict` - Boolean. Whether or not to be a jerk. Default: `false`.
|
||||
|
||||
`opt` - Object bag of settings regarding string formatting. All default to `false`.
|
||||
|
||||
Settings supported:
|
||||
|
||||
* `trim` - Boolean. Whether or not to trim text and comment nodes.
|
||||
* `normalize` - Boolean. If true, then turn any whitespace into a single
|
||||
space.
|
||||
* `lowercasetags` - Boolean. If true, then lowercase tags in loose mode,
|
||||
rather than uppercasing them.
|
||||
* `xmlns` - Boolean. If true, then namespaces are supported.
|
||||
|
||||
## Methods
|
||||
|
||||
`write` - Write bytes onto the stream. You don't have to do this all at
|
||||
once. You can keep writing as much as you want.
|
||||
|
||||
`close` - Close the stream. Once closed, no more data may be written until
|
||||
it is done processing the buffer, which is signaled by the `end` event.
|
||||
|
||||
`resume` - To gracefully handle errors, assign a listener to the `error`
|
||||
event. Then, when the error is taken care of, you can call `resume` to
|
||||
continue parsing. Otherwise, the parser will not continue while in an error
|
||||
state.
|
||||
|
||||
## Members
|
||||
|
||||
At all times, the parser object will have the following members:
|
||||
|
||||
`line`, `column`, `position` - Indications of the position in the XML
|
||||
document where the parser currently is looking.
|
||||
|
||||
`startTagPosition` - Indicates the position where the current tag starts.
|
||||
|
||||
`closed` - Boolean indicating whether or not the parser can be written to.
|
||||
If it's `true`, then wait for the `ready` event to write again.
|
||||
|
||||
`strict` - Boolean indicating whether or not the parser is a jerk.
|
||||
|
||||
`opt` - Any options passed into the constructor.
|
||||
|
||||
`tag` - The current tag being dealt with.
|
||||
|
||||
And a bunch of other stuff that you probably shouldn't touch.
|
||||
|
||||
## Events
|
||||
|
||||
All events emit with a single argument. To listen to an event, assign a
|
||||
function to `on<eventname>`. Functions get executed in the this-context of
|
||||
the parser object. The list of supported events are also in the exported
|
||||
`EVENTS` array.
|
||||
|
||||
When using the stream interface, assign handlers using the EventEmitter
|
||||
`on` function in the normal fashion.
|
||||
|
||||
`error` - Indication that something bad happened. The error will be hanging
|
||||
out on `parser.error`, and must be deleted before parsing can continue. By
|
||||
listening to this event, you can keep an eye on that kind of stuff. Note:
|
||||
this happens *much* more in strict mode. Argument: instance of `Error`.
|
||||
|
||||
`text` - Text node. Argument: string of text.
|
||||
|
||||
`doctype` - The `<!DOCTYPE` declaration. Argument: doctype string.
|
||||
|
||||
`processinginstruction` - Stuff like `<?xml foo="blerg" ?>`. Argument:
|
||||
object with `name` and `body` members. Attributes are not parsed, as
|
||||
processing instructions have implementation dependent semantics.
|
||||
|
||||
`sgmldeclaration` - Random SGML declarations. Stuff like `<!ENTITY p>`
|
||||
would trigger this kind of event. This is a weird thing to support, so it
|
||||
might go away at some point. SAX isn't intended to be used to parse SGML,
|
||||
after all.
|
||||
|
||||
`opentag` - An opening tag. Argument: object with `name` and `attributes`.
|
||||
In non-strict mode, tag names are uppercased, unless the `lowercasetags`
|
||||
option is set. If the `xmlns` option is set, then it will contain
|
||||
namespace binding information on the `ns` member, and will have a
|
||||
`local`, `prefix`, and `uri` member.
|
||||
|
||||
`closetag` - A closing tag. In loose mode, tags are auto-closed if their
|
||||
parent closes. In strict mode, well-formedness is enforced. Note that
|
||||
self-closing tags will have `closeTag` emitted immediately after `openTag`.
|
||||
Argument: tag name.
|
||||
|
||||
`attribute` - An attribute node. Argument: object with `name` and `value`,
|
||||
and also namespace information if the `xmlns` option flag is set.
|
||||
|
||||
`comment` - A comment node. Argument: the string of the comment.
|
||||
|
||||
`opencdata` - The opening tag of a `<![CDATA[` block.
|
||||
|
||||
`cdata` - The text of a `<![CDATA[` block. Since `<![CDATA[` blocks can get
|
||||
quite large, this event may fire multiple times for a single block, if it
|
||||
is broken up into multiple `write()`s. Argument: the string of random
|
||||
character data.
|
||||
|
||||
`closecdata` - The closing tag (`]]>`) of a `<![CDATA[` block.
|
||||
|
||||
`opennamespace` - If the `xmlns` option is set, then this event will
|
||||
signal the start of a new namespace binding.
|
||||
|
||||
`closenamespace` - If the `xmlns` option is set, then this event will
|
||||
signal the end of a namespace binding.
|
||||
|
||||
`end` - Indication that the closed stream has ended.
|
||||
|
||||
`ready` - Indication that the stream has reset, and is ready to be written
|
||||
to.
|
||||
|
||||
`noscript` - In non-strict mode, `<script>` tags trigger a `"script"`
|
||||
event, and their contents are not checked for special xml characters.
|
||||
If you pass `noscript: true`, then this behavior is suppressed.
|
||||
|
||||
## Reporting Problems
|
||||
|
||||
It's best to write a failing test if you find an issue. I will always
|
||||
accept pull requests with failing tests if they demonstrate intended
|
||||
behavior, but it is very hard to figure out what issue you're describing
|
||||
without a test. Writing a test is also the best way for you yourself
|
||||
to figure out if you really understand the issue you think you have with
|
||||
sax-js.
|
||||
+1006
File diff suppressed because it is too large
Load Diff
+89
@@ -0,0 +1,89 @@
|
||||
{
|
||||
"name": "sax",
|
||||
"description": "An evented streaming XML parser in JavaScript",
|
||||
"author": {
|
||||
"name": "Isaac Z. Schlueter",
|
||||
"email": "i@izs.me",
|
||||
"url": "http://blog.izs.me/"
|
||||
},
|
||||
"version": "0.3.5",
|
||||
"main": "lib/sax.js",
|
||||
"license": {
|
||||
"type": "MIT",
|
||||
"url": "https://raw.github.com/isaacs/sax-js/master/LICENSE"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node test/index.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/isaacs/sax-js.git"
|
||||
},
|
||||
"_npmUser": {
|
||||
"name": "isaacs",
|
||||
"email": "i@izs.me"
|
||||
},
|
||||
"_id": "sax@0.3.5",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Isaac Z. Schlueter",
|
||||
"email": "i@izs.me"
|
||||
},
|
||||
{
|
||||
"name": "Stein Martin Hustad",
|
||||
"email": "stein@hustad.com"
|
||||
},
|
||||
{
|
||||
"name": "Mikeal Rogers",
|
||||
"email": "mikeal.rogers@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Laurie Harper",
|
||||
"email": "laurie@holoweb.net"
|
||||
},
|
||||
{
|
||||
"name": "Jann Horn",
|
||||
"email": "jann@Jann-PC.fritz.box"
|
||||
},
|
||||
{
|
||||
"name": "Elijah Insua",
|
||||
"email": "tmpvar@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Henry Rawas",
|
||||
"email": "henryr@schakra.com"
|
||||
},
|
||||
{
|
||||
"name": "Justin Makeig",
|
||||
"email": "jmpublic@makeig.com"
|
||||
}
|
||||
],
|
||||
"dependencies": {},
|
||||
"devDependencies": {},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"_engineSupported": true,
|
||||
"_npmVersion": "1.1.0-beta-7",
|
||||
"_nodeVersion": "v0.6.7-pre",
|
||||
"_defaultsLoaded": true,
|
||||
"dist": {
|
||||
"shasum": "88fcfc1f73c0c8bbd5b7c776b6d3f3501eed073d",
|
||||
"tarball": "http://registry.npmjs.org/sax/-/sax-0.3.5.tgz"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "isaacs",
|
||||
"email": "i@izs.me"
|
||||
}
|
||||
],
|
||||
"directories": {},
|
||||
"_shasum": "88fcfc1f73c0c8bbd5b7c776b6d3f3501eed073d",
|
||||
"_resolved": "https://registry.npmjs.org/sax/-/sax-0.3.5.tgz",
|
||||
"_from": "sax@0.3.5",
|
||||
"bugs": {
|
||||
"url": "https://github.com/isaacs/sax-js/issues"
|
||||
},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"homepage": "https://github.com/isaacs/sax-js#readme"
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"author": {
|
||||
"name": "Rackspace US, Inc."
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Paul Querna",
|
||||
"email": "paul.querna@rackspace.com"
|
||||
},
|
||||
{
|
||||
"name": "Tomaz Muraus",
|
||||
"email": "tomaz.muraus@rackspace.com"
|
||||
}
|
||||
],
|
||||
"name": "elementtree",
|
||||
"description": "XML Serialization and Parsing module based on Python's ElementTree.",
|
||||
"version": "0.1.6",
|
||||
"keywords": [
|
||||
"xml",
|
||||
"sax",
|
||||
"parser",
|
||||
"seralization",
|
||||
"elementtree"
|
||||
],
|
||||
"homepage": "https://github.com/racker/node-elementtree",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/racker/node-elementtree.git"
|
||||
},
|
||||
"main": "lib/elementtree.js",
|
||||
"directories": {
|
||||
"lib": "lib"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "make test"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"sax": "0.3.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"whiskey": "0.8.x"
|
||||
},
|
||||
"licenses": [
|
||||
{
|
||||
"type": "Apache",
|
||||
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
|
||||
}
|
||||
],
|
||||
"bugs": {
|
||||
"url": "https://github.com/racker/node-elementtree/issues"
|
||||
},
|
||||
"_id": "elementtree@0.1.6",
|
||||
"dist": {
|
||||
"shasum": "2ac4c46ea30516c8c4cbdb5e3ac7418e592de20c",
|
||||
"tarball": "http://registry.npmjs.org/elementtree/-/elementtree-0.1.6.tgz"
|
||||
},
|
||||
"_from": "elementtree@>=0.1.6 <0.2.0",
|
||||
"_npmVersion": "1.3.24",
|
||||
"_npmUser": {
|
||||
"name": "rphillips",
|
||||
"email": "ryan@trolocsis.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "rphillips",
|
||||
"email": "ryan@trolocsis.com"
|
||||
}
|
||||
],
|
||||
"_shasum": "2ac4c46ea30516c8c4cbdb5e3ac7418e592de20c",
|
||||
"_resolved": "https://registry.npmjs.org/elementtree/-/elementtree-0.1.6.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
}
|
||||
Reference in New Issue
Block a user