Skip to content

Commit 27e81e0

Browse files
committed
Add ability to toString a fragment, without declarations and all that bullshit. Add ability to set a raw value in writer
1 parent aacbbe8 commit 27e81e0

File tree

4 files changed

+97
-21
lines changed

4 files changed

+97
-21
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "njs-tfso-xml",
3-
"version": "1.0.2",
3+
"version": "1.1.0",
44
"main": "./index.js",
55
"scripts": {
66
"test": "mocha --recursive ./test/**/test*"

src/XmlReader.js

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ const parse = require('./parse')
66
const XmlWriter = require('./XmlWriter')
77

88
class XmlReader{
9-
constructor(data, documentTag){
9+
constructor(data, currentTag){
1010
this.data = data
11-
this.documentTag = documentTag
11+
this.currentTag = currentTag
1212
}
1313

1414
static streamParseFromString(xmlString, splitOn){
@@ -23,6 +23,10 @@ class XmlReader{
2323
}))
2424
}
2525

26+
/**
27+
* @param xmlString
28+
* @returns {Promise<XmlReader>}
29+
*/
2630
static async parse(xmlString){
2731
return parse(xmlString)
2832
.then(({data, documentTag}) => {
@@ -55,7 +59,7 @@ class XmlReader{
5559
}
5660

5761
keys(){
58-
return Object.keys(this.data.children || {})
62+
return Object.keys((this.data && this.data.children) || {})
5963
}
6064

6165
/**
@@ -65,9 +69,10 @@ class XmlReader{
6569
* @returns {XmlReader}
6670
*/
6771
asObject(path){
72+
const tag = path.split('.').reverse()[0]
6873
path = path.replace(/\./g, '.0.children.')
6974
path = `children.${path}.0`
70-
return new XmlReader(_.get(this.data, path))
75+
return new XmlReader(_.get(this.data, path), tag)
7176
}
7277

7378
/**
@@ -78,9 +83,10 @@ class XmlReader{
7883
* @returns {XmlReader[]}
7984
*/
8085
asArray(path){
86+
const tag = path.split('.').reverse()[0]
8187
path = path.replace(/\./g, '.0.children.')
8288
path = `children.${path}`
83-
return _.get(this.data, path, []).map(obj => new XmlReader(obj))
89+
return _.get(this.data, path, []).map(obj => new XmlReader(obj, tag))
8490
}
8591

8692
/**
@@ -95,12 +101,12 @@ class XmlReader{
95101
return []
96102
}
97103

98-
let parts = path.split('.')
104+
const parts = path.split('.')
99105

100-
let firstPath = parts[0]
101-
let remainingPath = parts.slice(1).join('.')
106+
const firstPath = parts[0]
107+
const remainingPath = parts.slice(1).join('.')
102108

103-
let curr = this.asArray(firstPath)
109+
const curr = this.asArray(firstPath)
104110

105111
if(remainingPath.length === 0){
106112
return curr
@@ -116,6 +122,10 @@ class XmlReader{
116122
toString(){
117123
return XmlWriter.fromReader(this).toString()
118124
}
125+
126+
toFragmentString(){
127+
return XmlWriter.fromReader(this).toFragmentString()
128+
}
119129
}
120130

121131
module.exports = XmlReader

src/XmlWriter.js

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
const DOMImplementation = require('xmldom').DOMImplementation
22
const XMLSerializer = require('xmldom').XMLSerializer
3+
const DOMParser = require('xmldom').DOMParser
4+
const XmlReader = require('./XmlReader')
35

46
class XmlWriter{
57
/**
@@ -19,11 +21,11 @@ class XmlWriter{
1921
* @returns {XmlWriter}
2022
*/
2123
static create(namespace, namespaceURI, schemaLocation, documentName = 'Document'){
22-
let dom = new DOMImplementation()
23-
let doc = dom.createDocument(namespace, documentName)
24+
const dom = new DOMImplementation()
25+
const doc = dom.createDocument(namespace, documentName)
2426

2527
doc.insertBefore(doc.createProcessingInstruction('xml', 'version="1.0" encoding="utf-8"'), doc.documentElement)
26-
let documentElement = doc.documentElement
28+
const documentElement = doc.documentElement
2729

2830
if(namespaceURI && schemaLocation){
2931
documentElement.setAttributeNS(namespaceURI, 'xsi:schemaLocation', schemaLocation)
@@ -37,7 +39,7 @@ class XmlWriter{
3739
* @returns {*}
3840
*/
3941
static fromReader(reader){
40-
let writer = XmlWriter.create('', '', '', reader.documentTag)
42+
const writer = XmlWriter.create('', '', '', reader.currentTag)
4143

4244
/**
4345
* @param {XmlReader} reader
@@ -46,7 +48,7 @@ class XmlWriter{
4648
let write = (reader, writer) => {
4749
for(let key of reader.keys()){
4850
for(let obj of reader.asArray(key)){
49-
let writeChildren = nextWriter => write(obj, nextWriter)
51+
const writeChildren = nextWriter => write(obj, nextWriter)
5052
writer.add(key, writeChildren, obj.attributes(), obj.val())
5153
}
5254
}
@@ -82,13 +84,13 @@ class XmlWriter{
8284
* @returns {XmlWriter}
8385
*/
8486
addAndGet(path, valueOrFunctionOrNull = null, attributes = null, value = null){
85-
let parts = path.split('.')
86-
let firstPath = parts[0]
87-
let remainingPath = parts.slice(1).join('.')
87+
const parts = path.split('.')
88+
const firstPath = parts[0]
89+
const remainingPath = parts.slice(1).join('.')
8890

89-
let elem = this._doc.createElementNS(this._doc.documentElement.namespaceURI, firstPath)
91+
const elem = this._doc.createElementNS(this._doc.documentElement.namespaceURI, firstPath)
9092
this._elem.appendChild(elem)
91-
let writer = new XmlWriter(this._doc, elem)
93+
const writer = new XmlWriter(this._doc, elem)
9294

9395
if(remainingPath.length === 0){
9496
if(typeof valueOrFunctionOrNull === 'function'){
@@ -112,6 +114,12 @@ class XmlWriter{
112114
return writer.addAndGet(remainingPath, valueOrFunctionOrNull, attributes)
113115
}
114116

117+
setValRaw(raw){
118+
const parser = new DOMParser()
119+
this._elem.appendChild(parser.parseFromString(raw))
120+
return this
121+
}
122+
115123
setVal(value){
116124
this._elem.textContent = value
117125
return this
@@ -123,9 +131,17 @@ class XmlWriter{
123131
}
124132

125133
toString(){
126-
let s = new XMLSerializer()
134+
const s = new XMLSerializer()
127135
return s.serializeToString(this._doc)
128136
}
137+
138+
/**
139+
* toString of the current document element
140+
*/
141+
toFragmentString(){
142+
const s = new XMLSerializer()
143+
return s.serializeToString(this._elem)
144+
}
129145
}
130146

131147
module.exports = XmlWriter

test/testXmlWriter.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
const XmlReader = require('../src/XmlReader')
2+
const XmlWriter = require('../src/XmlWriter')
3+
const chai = require('chai')
4+
5+
let testData1 = `
6+
<document>
7+
<test hello="world">yo</test>
8+
<list>
9+
<otheritem>yoyo</otheritem>
10+
<item>
11+
<nestedlist>
12+
<nesteditem attr="attr1">1</nesteditem>
13+
<nesteditem attr="attr2">2</nesteditem>
14+
</nestedlist>
15+
</item>
16+
<item>
17+
<nestedlist>
18+
<nesteditem attr="attr3">3</nesteditem>
19+
<nesteditem attr="attr4">4</nesteditem>
20+
</nestedlist>
21+
</item>
22+
</list>
23+
</document>
24+
`
25+
26+
describe('XmlWriter', () => {
27+
it('should be able to print a fragment', async () => {
28+
const reader = await XmlReader.parse(testData1)
29+
30+
const subReader = reader.asObject('list.item')
31+
32+
const writer = XmlWriter.fromReader(subReader)
33+
34+
const finalReader = await XmlReader.parse(writer.toFragmentString())
35+
36+
chai.expect(finalReader.valAt('nestedlist.nesteditem')).to.equal('1')
37+
})
38+
39+
it('should set a raw value', async () => {
40+
const writer = XmlWriter.create('', '', '', 'Document')
41+
42+
writer.setValRaw(`
43+
<test>hello!</test>
44+
`)
45+
46+
const reader = await XmlReader.parse(writer.toString())
47+
48+
chai.expect(reader.valAt('test')).to.equal('hello!')
49+
})
50+
})

0 commit comments

Comments
 (0)