@flighthq/xml 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export type { XmlElement } from './xmlParse';
2
2
  export { parseXmlAttributes, parseXmlDocument } from './xmlParse';
3
+ export { getXmlElementAttribute, getXmlElementAttributeNumber, getXmlElementChildByName, getXmlElementChildrenByName, } from './xmlQuery';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,EACL,sBAAsB,EACtB,4BAA4B,EAC5B,wBAAwB,EACxB,2BAA2B,GAC5B,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export { parseXmlAttributes, parseXmlDocument } from './xmlParse';
2
+ export { getXmlElementAttribute, getXmlElementAttributeNumber, getXmlElementChildByName, getXmlElementChildrenByName, } from './xmlQuery';
2
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,EACL,sBAAsB,EACtB,4BAA4B,EAC5B,wBAAwB,EACxB,2BAA2B,GAC5B,MAAM,YAAY,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"xmlParse.d.ts","sourceRoot":"","sources":["../src/xmlParse.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,kFAAkF;IAClF,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;CACd;AAED;8EAC8E;AAC9E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAWxE;AAED;;qEAEqE;AACrE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAW/D"}
1
+ {"version":3,"file":"xmlParse.d.ts","sourceRoot":"","sources":["../src/xmlParse.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,kFAAkF;IAClF,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;CACd;AAED;8EAC8E;AAC9E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAWxE;AAED;;qEAEqE;AACrE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAY/D"}
package/dist/xmlParse.js CHANGED
@@ -1,4 +1,4 @@
1
- // Pull-style XML parser sufficient for atlas and plist file formats.
1
+ // Tree-building (DOM-style) XML parser sufficient for atlas and plist file formats.
2
2
  // Not a general-purpose XML parser, but handles namespaced/extra attributes and elements,
3
3
  // both double-quoted and single-quoted attribute values, XML entity escapes
4
4
  // (&amp; &lt; &gt; &quot; &apos; plus numeric references), XML comments (<!-- -->),
@@ -23,10 +23,11 @@ export function parseXmlAttributes(attrs) {
23
23
  export function parseXmlDocument(xml) {
24
24
  // Normalize: strip comments, process CDATA, normalize line endings
25
25
  let src = stripCdata(stripXmlComments(xml)).replace(/\r\n?/g, '\n');
26
- // Strip XML declaration and DOCTYPE if present
26
+ // Strip XML declaration and DOCTYPE (including an internal subset `[ ... ]`,
27
+ // whose contents may hold `>` characters the flat `[^>]*` form would stop at).
27
28
  src = src
28
29
  .replace(/<\?[\s\S]*?\?>/g, '')
29
- .replace(/<!DOCTYPE[^>]*>/gi, '')
30
+ .replace(/<!DOCTYPE[^>[]*(?:\[[\s\S]*?\][^>]*)?>/gi, '')
30
31
  .trim();
31
32
  return parseElement(src, { pos: 0 });
32
33
  }
@@ -66,10 +67,24 @@ function parseElement(src, state) {
66
67
  if (!name)
67
68
  return null;
68
69
  skipWhitespace(src, state);
69
- // Read attributes (everything up to '>' or '/')
70
+ // Read attributes up to the tag end. Track the active quote so a '>' inside a
71
+ // quoted attribute value (e.g. a TexturePacker/Starling value like "a>b") is
72
+ // treated as data rather than ending the tag.
70
73
  let attrsStr = '';
71
- while (state.pos < src.length && src[state.pos] !== '>' && !(src[state.pos] === '/' && src[state.pos + 1] === '>')) {
72
- attrsStr += src[state.pos];
74
+ let quote = '';
75
+ while (state.pos < src.length) {
76
+ const ch = src[state.pos];
77
+ if (quote) {
78
+ if (ch === quote)
79
+ quote = '';
80
+ }
81
+ else if (ch === '"' || ch === "'") {
82
+ quote = ch;
83
+ }
84
+ else if (ch === '>' || (ch === '/' && src[state.pos + 1] === '>')) {
85
+ break;
86
+ }
87
+ attrsStr += ch;
73
88
  state.pos++;
74
89
  }
75
90
  const selfClosing = src[state.pos] === '/';
@@ -1 +1 @@
1
- {"version":3,"file":"xmlParse.js","sourceRoot":"","sources":["../src/xmlParse.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"xmlParse.js","sourceRoot":"","sources":["../src/xmlParse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { XmlElement } from './xmlParse';
2
+ /** The attribute value for `name`, or null when the element has no such attribute. */
3
+ export declare function getXmlElementAttribute(element: Readonly<XmlElement>, name: string): string | null;
4
+ /** The attribute value for `name` parsed as a number, or null when the
5
+ * attribute is absent or does not parse to a finite number. */
6
+ export declare function getXmlElementAttributeNumber(element: Readonly<XmlElement>, name: string): number | null;
7
+ /** The first direct child element with tag name `name`, or null when none matches. */
8
+ export declare function getXmlElementChildByName(element: Readonly<XmlElement>, name: string): XmlElement | null;
9
+ /** All direct child elements with tag name `name`, in document order (empty when none match). */
10
+ export declare function getXmlElementChildrenByName(element: Readonly<XmlElement>, name: string): XmlElement[];
11
+ //# sourceMappingURL=xmlQuery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xmlQuery.d.ts","sourceRoot":"","sources":["../src/xmlQuery.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,sFAAsF;AACtF,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGjG;AAED;gEACgE;AAChE,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKvG;AAED,sFAAsF;AACtF,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAKvG;AAED,iGAAiG;AACjG,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,CAErG"}
@@ -0,0 +1,30 @@
1
+ // Read-only query helpers over a parsed XmlElement tree, so consumers stop
2
+ // hand-filtering `children` and `attributes` at every call site. All lookups
3
+ // return a sentinel (null) rather than throwing when the name is absent.
4
+ /** The attribute value for `name`, or null when the element has no such attribute. */
5
+ export function getXmlElementAttribute(element, name) {
6
+ const value = element.attributes[name];
7
+ return value !== undefined ? value : null;
8
+ }
9
+ /** The attribute value for `name` parsed as a number, or null when the
10
+ * attribute is absent or does not parse to a finite number. */
11
+ export function getXmlElementAttributeNumber(element, name) {
12
+ const value = element.attributes[name];
13
+ if (value === undefined || value.trim() === '')
14
+ return null;
15
+ const parsed = Number(value);
16
+ return Number.isFinite(parsed) ? parsed : null;
17
+ }
18
+ /** The first direct child element with tag name `name`, or null when none matches. */
19
+ export function getXmlElementChildByName(element, name) {
20
+ for (const child of element.children) {
21
+ if (child.name === name)
22
+ return child;
23
+ }
24
+ return null;
25
+ }
26
+ /** All direct child elements with tag name `name`, in document order (empty when none match). */
27
+ export function getXmlElementChildrenByName(element, name) {
28
+ return element.children.filter((child) => child.name === name);
29
+ }
30
+ //# sourceMappingURL=xmlQuery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xmlQuery.js","sourceRoot":"","sources":["../src/xmlQuery.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,6EAA6E;AAC7E,yEAAyE;AAIzE,sFAAsF;AACtF,MAAM,UAAU,sBAAsB,CAAC,OAA6B,EAAE,IAAY;IAChF,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5C,CAAC;AAED;gEACgE;AAChE,MAAM,UAAU,4BAA4B,CAAC,OAA6B,EAAE,IAAY;IACtF,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAC5D,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACjD,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,wBAAwB,CAAC,OAA6B,EAAE,IAAY;IAClF,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrC,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;IACxC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,2BAA2B,CAAC,OAA6B,EAAE,IAAY;IACrF,OAAO,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AACjE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,11 @@
1
1
  {
2
2
  "name": "@flighthq/xml",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/flighthq/flight.git",
7
+ "directory": "packages/xml"
8
+ },
4
9
  "type": "module",
5
10
  "main": "dist/index.js",
6
11
  "types": "dist/index.d.ts",
@@ -29,6 +34,6 @@
29
34
  "devDependencies": {
30
35
  "typescript": "^5.3.0"
31
36
  },
32
- "description": "Lightweight pull-style XML parser: parseXmlDocument and parseXmlAttributes for atlas, plist, and sprite-sheet format files",
37
+ "description": "Lightweight tree-building (DOM-style) XML parser: parseXmlDocument builds an XmlElement tree, plus parseXmlAttributes and element query helpers, for atlas, plist, and sprite-sheet format files",
33
38
  "sideEffects": false
34
39
  }
@@ -135,4 +135,27 @@ describe('parseXmlDocument', () => {
135
135
  const doc = parseXmlDocument(xml);
136
136
  expect(doc?.children[0]?.text).toBe('hello');
137
137
  });
138
+
139
+ it('keeps a > inside a quoted attribute value as data, not tag-end', () => {
140
+ const root = parseXmlDocument('<node attr="a>b"/>');
141
+ expect(root?.name).toBe('node');
142
+ expect(root?.attributes.attr).toBe('a>b');
143
+ expect(root?.children).toEqual([]);
144
+ });
145
+
146
+ it('keeps a > inside a single-quoted attribute value and still parses children', () => {
147
+ const root = parseXmlDocument(`<root><child path='x>y'/></root>`);
148
+ expect(root?.children.length).toBe(1);
149
+ expect(root?.children[0].attributes.path).toBe('x>y');
150
+ });
151
+
152
+ it('strips a DOCTYPE that carries an internal subset', () => {
153
+ const xml =
154
+ '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" ' +
155
+ '"http://www.apple.com/DTDs/PropertyList-1.0.dtd" [ <!ENTITY x "y"> ]>' +
156
+ '<plist version="1.0"/>';
157
+ const doc = parseXmlDocument(xml);
158
+ expect(doc?.name).toBe('plist');
159
+ expect(doc?.attributes.version).toBe('1.0');
160
+ });
138
161
  });
@@ -0,0 +1,68 @@
1
+ import { parseXmlDocument } from './xmlParse';
2
+ import {
3
+ getXmlElementAttribute,
4
+ getXmlElementAttributeNumber,
5
+ getXmlElementChildByName,
6
+ getXmlElementChildrenByName,
7
+ } from './xmlQuery';
8
+
9
+ describe('getXmlElementAttribute', () => {
10
+ it('returns the attribute value when present', () => {
11
+ const root = parseXmlDocument('<node name="hero" x="10"/>');
12
+ expect(getXmlElementAttribute(root!, 'name')).toBe('hero');
13
+ });
14
+
15
+ it('returns null when the attribute is absent', () => {
16
+ const root = parseXmlDocument('<node name="hero"/>');
17
+ expect(getXmlElementAttribute(root!, 'missing')).toBeNull();
18
+ });
19
+
20
+ it('returns an empty-string attribute rather than null', () => {
21
+ const root = parseXmlDocument('<node label=""/>');
22
+ expect(getXmlElementAttribute(root!, 'label')).toBe('');
23
+ });
24
+ });
25
+
26
+ describe('getXmlElementAttributeNumber', () => {
27
+ it('parses a numeric attribute', () => {
28
+ const root = parseXmlDocument('<node x="10" scale="1.5"/>');
29
+ expect(getXmlElementAttributeNumber(root!, 'x')).toBe(10);
30
+ expect(getXmlElementAttributeNumber(root!, 'scale')).toBe(1.5);
31
+ });
32
+
33
+ it('returns null when the attribute is absent', () => {
34
+ const root = parseXmlDocument('<node x="10"/>');
35
+ expect(getXmlElementAttributeNumber(root!, 'missing')).toBeNull();
36
+ });
37
+
38
+ it('returns null when the value is not a finite number', () => {
39
+ const root = parseXmlDocument('<node x="abc" y=""/>');
40
+ expect(getXmlElementAttributeNumber(root!, 'x')).toBeNull();
41
+ expect(getXmlElementAttributeNumber(root!, 'y')).toBeNull();
42
+ });
43
+ });
44
+
45
+ describe('getXmlElementChildByName', () => {
46
+ it('returns the first matching child element', () => {
47
+ const root = parseXmlDocument('<root><a id="1"/><b/><a id="2"/></root>');
48
+ expect(getXmlElementChildByName(root!, 'a')?.attributes.id).toBe('1');
49
+ });
50
+
51
+ it('returns null when no child matches', () => {
52
+ const root = parseXmlDocument('<root><a/></root>');
53
+ expect(getXmlElementChildByName(root!, 'z')).toBeNull();
54
+ });
55
+ });
56
+
57
+ describe('getXmlElementChildrenByName', () => {
58
+ it('returns all matching children in document order', () => {
59
+ const root = parseXmlDocument('<root><a id="1"/><b/><a id="2"/></root>');
60
+ const matches = getXmlElementChildrenByName(root!, 'a');
61
+ expect(matches.map((c) => c.attributes.id)).toEqual(['1', '2']);
62
+ });
63
+
64
+ it('returns an empty array when no child matches', () => {
65
+ const root = parseXmlDocument('<root><a/></root>');
66
+ expect(getXmlElementChildrenByName(root!, 'z')).toEqual([]);
67
+ });
68
+ });