diff --git a/README.md b/README.md
index 9c60762..2c02887 100644
--- a/README.md
+++ b/README.md
@@ -468,16 +468,24 @@ For comparing a binary file, simply point the response to the binary file:
If the response format is specified as `"type": "xml"` or `"type": "xml2"`, we internally marshal that XML into json using [github.com/clbanning/mxj](https://github.com/clbanning/mxj).
-The format `"xml"` uses `NewMapXmlSeq()`, whereas the format `"xml2"` uses `NewMapXml()`, which provides a simpler json format (see also template [`file_xml2json`](#file_xml2json-path)).
+The format `"xml"` uses `NewMapXmlSeq()`, whereas the format `"xml2"` uses `NewMapXml()`, which provides a simpler json format.
+
+See also template [`file_xml2json`](#file_xml2json-path).
On that json you can work as you are used to with the json syntax. For seeing how the converted json looks you can use the `--log-verbose` command line flag
+## XHTML Data comparison
+
+If the response format is specified as `"type": "xhtml"`, we internally marshal that XHTML into json using [github.com/clbanning/mxj](https://github.com/clbanning/mxj).
+
+The XHTML code in the response must comply to the [XHTML standard](https://www.w3.org/TR/xhtml1/), which means it must be parsable as XML.
+
+See also template [`file_xhtml2json`](#file_xhtml2json-path).
+
## CSV Data comparison
If the response format is specified as `"type": "csv"`, we internally marshal that CSV into json.
-On that json you can work as you are used to with the json syntax. For seeing how the converted json looks you can use the `--log-verbose` command line flag
-
You can also specify the delimiter (`comma`) for the CSV format (default: `,`):
```yaml
@@ -1795,7 +1803,7 @@ int64,string
## `file_xml2json [path]`
Helper function to parse an XML file and convert it into json
-- `@path`: string; a path to the xml file that should be loaded. The path is either relative to the manifest or a weburl
+- `@path`: string; a path to the XML file that should be loaded. The path is either relative to the manifest or a weburl
This function uses the function `NewMapXml()` from [github.com/clbanning/mxj](https://github.com/clbanning/mxj).
@@ -1847,6 +1855,58 @@ would result in
}
```
+## `file_xhtml2json [path]`
+
+Helper function to parse an XHTML file and convert it into json
+- `@path`: string; a path to the XHTML file that should be loaded. The path is either relative to the manifest or a weburl
+
+### Example
+
+Content of XHTML file `some/path/example.xhtml`:
+
+```html
+
+
+
+
+ easydb documentation
+
+
+
Welcome to the easydb documentation
+
+
+```
+
+The call
+
+```django
+{{ file_xhtml2json "some/path/example.xhtml" }}
+```
+
+would result in
+
+```json
+{
+ "html": {
+ "-xmlns": "http://www.w3.org/1999/xhtml",
+ "head": {
+ "link": {
+ "-href": "/css/easydb.css",
+ "-rel": "stylesheet",
+ "-type": "text/css"
+ },
+ "title": "easydb documentation"
+ },
+ "body": {
+ "h1": {
+ "#text": "Welcome to the easydb documentation",
+ "-id": "welcome-to-the-easydb-documentation"
+ }
+ }
+ }
+}
+```
+
## `file_sqlite [path] [statement]`
Helper function to return the result of an SQL statement from a sqlite3 file.
diff --git a/pkg/lib/api/response.go b/pkg/lib/api/response.go
index 7f79b63..0aa8306 100755
--- a/pkg/lib/api/response.go
+++ b/pkg/lib/api/response.go
@@ -83,7 +83,7 @@ type ResponseSerialization struct {
type ResponseFormat struct {
IgnoreBody bool `json:"-"` // if true, do not try to parse the body (since it is not expected in the response)
- Type string `json:"type"` // default "json", allowed: "csv", "json", "xml", "xml2", "binary"
+ Type string `json:"type"` // default "json", allowed: "csv", "json", "xml", "xml2", "xhtml", "binary"
CSV struct {
Comma string `json:"comma,omitempty"`
} `json:"csv,omitempty"`
@@ -170,6 +170,11 @@ func (response Response) ServerResponseToGenericJSON(responseFormat ResponseForm
if err != nil {
return res, errors.Wrap(err, "Could not marshal xml to json")
}
+ case "xhtml":
+ bodyData, err = util.Xhtml2Json(resp.Body)
+ if err != nil {
+ return res, errors.Wrap(err, "Could not marshal xhtml to json")
+ }
case "csv":
runeComma := ','
if responseFormat.CSV.Comma != "" {
@@ -376,7 +381,7 @@ func (response Response) ToString() string {
body := resp.Body
switch resp.Format.Type {
- case "xml", "xml2", "csv":
+ case "xml", "xml2", "csv", "xhtml":
if utf8.Valid(body) {
bodyString, err = resp.ServerResponseToJsonString(true)
if err != nil {
diff --git a/pkg/lib/template/template_loader.go b/pkg/lib/template/template_loader.go
index 179e895..b16bb9d 100644
--- a/pkg/lib/template/template_loader.go
+++ b/pkg/lib/template/template_loader.go
@@ -186,6 +186,19 @@ func (loader *Loader) Render(
return string(bytes), nil
},
+ "file_xhtml2json": func(path string) (string, error) {
+ fileBytes, err := fileReadInternal(path, rootDir)
+ if err != nil {
+ return "", err
+ }
+
+ bytes, err := util.Xhtml2Json(fileBytes)
+ if err != nil {
+ return "", errors.Wrap(err, "Could not marshal xhtml to json")
+ }
+
+ return string(bytes), nil
+ },
"file_path": func(path string) string {
return util.LocalPath(path, rootDir)
},
diff --git a/pkg/lib/util/util.go b/pkg/lib/util/util.go
index 941d312..fed9916 100644
--- a/pkg/lib/util/util.go
+++ b/pkg/lib/util/util.go
@@ -75,3 +75,22 @@ func Xml2Json(rawXml []byte, format string) ([]byte, error) {
}
return json, nil
}
+
+// Xhtml2Json parses the raw xhtml data and converts it into a json string
+func Xhtml2Json(rawXhtml []byte) ([]byte, error) {
+ var (
+ mv mxj.Map
+ err error
+ )
+
+ mv, err = mxj.NewMapXml(rawXhtml)
+ if err != nil {
+ return []byte{}, errors.Wrap(err, "Could not parse xhtml")
+ }
+
+ json, err := mv.JsonIndent("", " ")
+ if err != nil {
+ return []byte{}, errors.Wrap(err, "Could not convert to json")
+ }
+ return json, nil
+}
diff --git a/test/xhtml/check_local_file_against_response.json b/test/xhtml/check_local_file_against_response.json
new file mode 100644
index 0000000..0e6e1e7
--- /dev/null
+++ b/test/xhtml/check_local_file_against_response.json
@@ -0,0 +1,18 @@
+[
+ {
+ "name": "Get existing XHTML file",
+ "request": {
+ "server_url": "{{ datastore "req_base_url" }}",
+ "endpoint": "bounce-json",
+ "method": "POST",
+ "body": {{ file_xhtml2json "sample.xhtml" }}
+ },
+ "response": {
+ "statuscode": 200,
+ "body": {
+ "header": {},
+ "body": {{ file "result_xhtml.json" }}
+ }
+ }
+ }
+]
\ No newline at end of file
diff --git a/test/xhtml/check_response_format_xhtml.json b/test/xhtml/check_response_format_xhtml.json
new file mode 100644
index 0000000..e8660d9
--- /dev/null
+++ b/test/xhtml/check_response_format_xhtml.json
@@ -0,0 +1,18 @@
+{
+ "name": "bounce XHTML file, use response format \"xhtml\"",
+ "request": {
+ "server_url": "{{ datastore "req_base_url" }}",
+ "endpoint": "bounce",
+ "method": "POST",
+ "body": {
+ "file": "@sample.xhtml"
+ },
+ "body_type": "multipart"
+ },
+ "response": {
+ "format": {
+ "type": "xhtml"
+ },
+ "body": {{ file "result_xhtml.json" }}
+ }
+}
\ No newline at end of file
diff --git a/test/xhtml/manifest.json b/test/xhtml/manifest.json
new file mode 100644
index 0000000..f3d66bc
--- /dev/null
+++ b/test/xhtml/manifest.json
@@ -0,0 +1,16 @@
+{{ $local_port:=":9999"}}
+{
+ "http_server": {
+ "addr": "{{ $local_port }}",
+ "dir": "../_res/assets",
+ "testmode": false
+ },
+ "store": {
+ "req_base_url": "http://localhost{{ $local_port }}"
+ },
+ "name": "XHTML tests",
+ "tests": [
+ "@check_local_file_against_response.json",
+ "@check_response_format_xhtml.json"
+ ]
+}
\ No newline at end of file
diff --git a/test/xhtml/result_xhtml.json b/test/xhtml/result_xhtml.json
new file mode 100644
index 0000000..c5b1d7b
--- /dev/null
+++ b/test/xhtml/result_xhtml.json
@@ -0,0 +1,27 @@
+{
+ "html": {
+ "-xmlns": "http://www.w3.org/1999/xhtml",
+ "head": {
+ "link": {
+ "-href": "/css/easydb.css",
+ "-rel": "stylesheet",
+ "-type": "text/css"
+ },
+ "title": "easydb documentation"
+ },
+ "body": {
+ "h1": {
+ "#text": "Welcome to the easydb documentation",
+ "-id": "welcome-to-the-easydb-documentation"
+ },
+ "h2": {
+ "#text": "General",
+ "-id": "general"
+ },
+ "p": [
+ "easydb is a flexible web application that allows customers to manage data and information for images and multimedia.",
+ "easydb has a flexible data model that allows each instance to be tailored to customer needs."
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/xhtml/sample.xhtml b/test/xhtml/sample.xhtml
new file mode 100644
index 0000000..908b5cb
--- /dev/null
+++ b/test/xhtml/sample.xhtml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+ easydb documentation
+
+
+
+
+
Welcome to the easydb documentation
+
General
+
easydb is a flexible web application that allows customers to manage data and information for images and multimedia.
+
+
+
easydb has a flexible data model that allows each instance to be tailored to customer needs.