feat: prettify XML response (#3079)

This commit is contained in:
Nivedin
2023-05-30 05:48:19 +05:30
committed by GitHub
parent 385a587cfd
commit 26e564288b
5 changed files with 60 additions and 63 deletions

View File

@@ -92,6 +92,7 @@
"vuedraggable-es": "^4.1.1",
"wonka": "^4.0.15",
"workbox-window": "^6.5.4",
"xml-formatter": "^3.4.1",
"yargs-parser": "^21.1.1"
},
"devDependencies": {

View File

@@ -84,6 +84,7 @@ import { useToast } from "@composables/toast"
import { isJSONContentType } from "~/helpers/utils/contenttypes"
import jsonLinter from "~/helpers/editor/linting/json"
import { readFileAsText } from "~/helpers/functional/files"
import xmlFormat from "xml-formatter"
type PossibleContentTypes = Exclude<
ValidContentTypes,
@@ -197,26 +198,10 @@ const prettifyRequestBody = () => {
}
const prettifyXML = (xml: string) => {
const PADDING = " ".repeat(2) // set desired indent size here
const reg = /(>)(<)(\/*)/g
let pad = 0
xml = xml.replace(reg, "$1\r\n$2$3")
return xml
.split("\r\n")
.map((node) => {
let indent = 0
if (node.match(/.+<\/\w[^>]*>$/)) {
indent = 0
} else if (node.match(/^<\/\w/) && pad > 0) {
pad -= 1
} else if (node.match(/^<\w[^>]*[^\/]>.*$/)) {
indent = 1
} else {
indent = 0
}
pad += indent
return PADDING.repeat(pad - indent) + node
})
.join("\r\n")
return xmlFormat(xml, {
indentation: " ",
collapseContent: true,
lineSeparator: "\n",
})
}
</script>

View File

@@ -38,6 +38,7 @@ import {
baseHighlightStyle,
} from "@helpers/editor/themes/baseTheme"
import { HoppEnvironmentPlugin } from "@helpers/editor/extensions/HoppEnvironment"
import xmlFormat from "xml-formatter"
import { platform } from "~/platform"
// TODO: Migrate from legacy mode
@@ -152,6 +153,27 @@ const getLanguage = (langMime: string): Language | null => {
return null
}
/**
* Uses xml-formatter to format the XML document
* @param doc Document to parse
* @param langMime Language mime type
* @returns Parsed document if mime type is xml, else returns the original document
*/
const parseDoc = (
doc: string | undefined,
langMime: string
): string | undefined => {
if (langMime === "application/xml" && doc) {
return xmlFormat(doc, {
indentation: " ",
collapseContent: true,
lineSeparator: "\n",
})
} else {
return doc
}
}
const getEditorLanguage = (
langMime: string,
linter: LinterDefinition | undefined,
@@ -261,7 +283,7 @@ export function useCodemirror(
view.value = new EditorView({
parent: el,
state: EditorState.create({
doc: value.value,
doc: parseDoc(value.value, options.extendedEditorConfig.mode ?? ""),
extensions,
}),
})

View File

@@ -6,6 +6,7 @@ import { pipe, flow } from "fp-ts/function"
import { tupleToRecord } from "~/helpers/functional/record"
import { safeParseJSON } from "~/helpers/functional/json"
import { optionChoose } from "~/helpers/functional/option"
import xmlFormat from "xml-formatter"
const isJSON = flow(safeParseJSON, O.isSome)
@@ -213,45 +214,18 @@ export function parseBody(
*/
/**
* Prettifies XML string
* Prettifies XML string using xml-formatter
* @param sourceXml The string to format
* @returns Indented XML string (uses spaces)
*/
function prettifyXml(sourceXml: string) {
return pipe(
O.tryCatch(() => {
const xmlDoc = new DOMParser().parseFromString(
sourceXml,
"application/xml"
)
if (xmlDoc.querySelector("parsererror")) {
throw new Error("Unstructured Body")
}
const xsltDoc = new DOMParser().parseFromString(
[
// describes how we want to modify the XML - indent everything
'<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">',
' <xsl:strip-space elements="*"/>',
' <xsl:template match="para[content-style][not(text())]">', // change to just text() to strip space in text nodes
' <xsl:value-of select="normalize-space(.)"/>',
" </xsl:template>",
' <xsl:template match="node()|@*">',
' <xsl:copy><xsl:apply-templates select="node()|@*"/></xsl:copy>',
" </xsl:template>",
' <xsl:output indent="yes"/>',
"</xsl:stylesheet>",
].join("\n"),
"application/xml"
)
const xsltProcessor = new XSLTProcessor()
xsltProcessor.importStylesheet(xsltDoc)
const resultDoc = xsltProcessor.transformToDocument(xmlDoc)
const resultXml = new XMLSerializer().serializeToString(resultDoc)
return resultXml
return xmlFormat(sourceXml, {
indentation: " ",
collapseContent: true,
lineSeparator: "\n",
})
})
)
}