Skip to content

Commit

Permalink
Add verbose output option. Fixes #30
Browse files Browse the repository at this point in the history
  • Loading branch information
oozcitak committed Jul 14, 2020
1 parent 4c07c72 commit ac49c2b
Show file tree
Hide file tree
Showing 7 changed files with 304 additions and 21 deletions.
47 changes: 31 additions & 16 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export interface XMLBuilderOptions {
* - offset - the offset of the invalid character
* - str - the input string
*/
invalidCharReplacement: string | ((char: string, offset:number, str: string) => string) | undefined
invalidCharReplacement: string | ((char: string, offset: number, str: string) => string) | undefined
}

/**
Expand Down Expand Up @@ -309,6 +309,11 @@ export type MapWriterOptions = BaseWriterOptions & {
* `false`.
*/
group?: boolean
/**
* Outputs child nodes as an array, even if the parent node has zero or one
* child nodes.
*/
verbose?: boolean
}

/**
Expand All @@ -322,6 +327,11 @@ export type ObjectWriterOptions = BaseWriterOptions & {
* `false`.
*/
group?: boolean
/**
* Outputs child nodes as an array, even if the parent node has zero or one
* child nodes.
*/
verbose?: boolean
}

/**
Expand Down Expand Up @@ -426,6 +436,11 @@ export type JSONWriterOptions = BaseWriterOptions & {
* `false`.
*/
group?: boolean
/**
* Outputs child nodes as an array, even if the parent node has zero or one
* child nodes.
*/
verbose?: boolean
}

/**
Expand Down Expand Up @@ -859,11 +874,11 @@ export interface XMLBuilder {
*/
toObject(writerOptions?: ObjectWriterOptions): XMLSerializedAsObject | XMLSerializedAsObjectArray

/**
* Converts the node into its object representation using ES6 maps.
*
* @param options - serialization options
*/
/**
* Converts the node into its object representation using ES6 maps.
*
* @param options - serialization options
*/
toObject(writerOptions: MapWriterOptions): XMLSerializedAsMap | XMLSerializedAsMapArray

/**
Expand Down Expand Up @@ -1143,13 +1158,13 @@ export type XMLBuilderCBOptions = CBWriterOptions & {
* Defines namespace aliases.
*/
namespaceAlias: { [key: string]: string | null }
/**
* Replacement for invalid characters in input strings.
* If `invalidCharReplacement` is a string, each invalid character in an input
* string will be replaced with it; otherwise if `invalidCharReplacement`
* is a function it will be passed each invalid character and should return
* a replacement character.
*/
/**
* Replacement for invalid characters in input strings.
* If `invalidCharReplacement` is a string, each invalid character in an input
* string will be replaced with it; otherwise if `invalidCharReplacement`
* is a function it will be passed each invalid character and should return
* a replacement character.
*/
invalidCharReplacement: string | ((substring: string, ...args: any[]) => string) | undefined
}

Expand All @@ -1162,7 +1177,7 @@ export type BaseCBWriterOptions = {
* - `"xml"` - Serializes the document as a string in XML format.
* - `"json"` - Serializes the document as a JSON string.
*/
format?: "xml" | "json"
format?: "xml" | "json"
/**
* Ensures that the document adheres to the syntax rules specified by the
* XML specification. If this flag is set and the document is not well-formed
Expand All @@ -1178,7 +1193,7 @@ export type BaseCBWriterOptions = {
/**
* Defines the options passed to the callback builder's XML writer.
*/
export type XMLCBWriterOptions = BaseCBWriterOptions & {
export type XMLCBWriterOptions = BaseCBWriterOptions & {
/** @inheritdoc */
format?: "xml"
/**
Expand Down Expand Up @@ -1231,7 +1246,7 @@ export type XMLCBWriterOptions = BaseCBWriterOptions & {
/**
* Defines the options passed to the callback builder's JSON writer.
*/
export type JSONCBWriterOptions = BaseCBWriterOptions & {
export type JSONCBWriterOptions = BaseCBWriterOptions & {
/** @inheritdoc */
format?: "json"
/**
Expand Down
6 changes: 4 additions & 2 deletions src/writers/MapWriter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,16 @@ export class MapWriter extends BaseWriter<MapWriterOptions, XMLSerializedAsMap |
format: "map",
wellFormed: false,
noDoubleEncoding: false,
group: false
group: false,
verbose: false
})

// convert to object
const objectWriterOptions: ObjectWriterOptions = applyDefaults(options, {
format: "object",
wellFormed: false,
noDoubleEncoding: false
noDoubleEncoding: false,
verbose: false
})
const objectWriter = new ObjectWriter(this._builderOptions)
const val = objectWriter.serialize(node, objectWriterOptions)
Expand Down
15 changes: 12 additions & 3 deletions src/writers/ObjectWriter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ export class ObjectWriter extends BaseWriter<ObjectWriterOptions, XMLSerializedA
format: "object",
wellFormed: false,
noDoubleEncoding: false,
group: false
group: false,
verbose: false
}) as Required<ObjectWriterOptions>

this._currentList = []
Expand Down Expand Up @@ -174,7 +175,11 @@ export class ObjectWriter extends BaseWriter<ObjectWriterOptions, XMLSerializedA
result.push({ [key]: eleGroup })
} else {
// single element node
result.push({ [key]: this._process(ele[key] as NodeList, options) })
if (options.verbose) {
result.push({ [key]: [this._process(ele[key] as NodeList, options) as any] })
} else {
result.push({ [key]: this._process(ele[key] as NodeList, options) })
}
}
break
}
Expand Down Expand Up @@ -237,7 +242,11 @@ export class ObjectWriter extends BaseWriter<ObjectWriterOptions, XMLSerializedA
obj[key] = eleGroup
} else {
// single element node
obj[key] = this._process(ele[key] as NodeList, options)
if (options.verbose) {
obj[key] = [this._process(ele[key] as NodeList, options) as any]
} else {
obj[key] = this._process(ele[key] as NodeList, options)
}
}
break
}
Expand Down
65 changes: 65 additions & 0 deletions test/issues/issue-030.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import $$ from "../TestHelpers";

describe("Replicate issue", () => {
// https://github.com/oozcitak/xmlbuilder2/issues/30
test("#30 - Conversion from XML to JSON array inconsistency", () => {
const input2 = $$.t`
<data>
<row id="0">
<TYPE>X</TYPE>
<ID>123</ID>
</row>
<row id="1">
<TYPE>Y</TYPE>
<ID>321</ID>
</row>
</data>`

const obj2 = $$.convert(input2, { format: 'object', verbose: true })
expect(obj2).toEqual(
{
"data": [
{
"row": [
{
"@id": "0",
"TYPE": [ "X" ],
"ID": [ "123" ]
},
{
"@id": "1",
"TYPE": [ "Y" ],
"ID": [ "321" ]
}
]
}
]
})
expect($$.create(obj2).end({ headless: true, prettyPrint: true })).toBe(input2)

const input1 = $$.t`
<data>
<row id="0">
<TYPE>X</TYPE>
<ID>123</ID>
</row>
</data>`
const obj1 = $$.convert(input1, { format: 'object', verbose: true })
expect(obj1).toEqual(
{
"data": [
{
"row": [
{
"@id": "0",
"TYPE": [ "X" ],
"ID": [ "123" ]
}
]
}
]
})
expect($$.create(obj1).end({ headless: true, prettyPrint: true })).toBe(input1)
})

})
72 changes: 72 additions & 0 deletions test/writers/JSONWriter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,4 +196,76 @@ describe('JSONWriter', () => {
expect(() => ele.end({ format: "json" })).toThrow()
})

test("verbose", () => {
const input2 = $$.t`
<data>
<row id="0">
<TYPE>X</TYPE>
<ID>123</ID>
</row>
<row id="1">
<TYPE>Y</TYPE>
<ID>321</ID>
</row>
</data>`

const json2 = $$.convert(input2, { format: 'json', verbose: true, prettyPrint: true })
expect(json2).toBe($$.t`
{
"data": [
{
"row": [
{
"@id": "0",
"TYPE": [
"X"
],
"ID": [
"123"
]
},
{
"@id": "1",
"TYPE": [
"Y"
],
"ID": [
"321"
]
}
]
}
]
}`)
expect($$.create(json2).end({ headless: true, prettyPrint: true })).toBe(input2)

const input1 = $$.t`
<data>
<row id="0">
<TYPE>X</TYPE>
<ID>123</ID>
</row>
</data>`
const json1 = $$.convert(input1, { format: 'json', verbose: true, prettyPrint: true })
expect(json1).toEqual($$.t`
{
"data": [
{
"row": [
{
"@id": "0",
"TYPE": [
"X"
],
"ID": [
"123"
]
}
]
}
]
}`)
expect($$.create(json1).end({ headless: true, prettyPrint: true })).toBe(input1)
})

})
60 changes: 60 additions & 0 deletions test/writers/MapWriter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,4 +169,64 @@ describe('MapWriter', () => {
expect(() => ele.end({ format: "map" })).toThrow()
})

test("verbose", () => {
const input2 = $$.t`
<data>
<row id="0">
<TYPE>X</TYPE>
<ID>123</ID>
</row>
<row id="1">
<TYPE>Y</TYPE>
<ID>321</ID>
</row>
</data>`

const result2 = $$.convert(input2, { format: 'map', verbose: true })
expect($$.printMap(result2)).toBe($$.t`
M{
data: [
M{
row: [
M{
@id: 0,
TYPE: [ X ],
ID: [ 123 ]
},
M{
@id: 1,
TYPE: [ Y ],
ID: [ 321 ]
}
]
}
]
}`)
expect($$.create(result2).end({ headless: true, prettyPrint: true })).toBe(input2)

const input1 = $$.t`
<data>
<row id="0">
<TYPE>X</TYPE>
<ID>123</ID>
</row>
</data>`
const result1 = $$.convert(input1, { format: 'map', verbose: true })
expect($$.printMap(result1)).toEqual($$.t`
M{
data: [
M{
row: [
M{
@id: 0,
TYPE: [ X ],
ID: [ 123 ]
}
]
}
]
}`)
expect($$.create(result1).end({ headless: true, prettyPrint: true })).toBe(input1)
})

})
Loading

0 comments on commit ac49c2b

Please sign in to comment.