Added XSLT transformations
This commit is contained in:
parent
84adff578f
commit
f295059159
12 changed files with 1715 additions and 1676 deletions
3176
package-lock.json
generated
3176
package-lock.json
generated
File diff suppressed because it is too large
Load diff
12
package.json
12
package.json
|
@ -23,7 +23,7 @@
|
|||
"url": "https://github.com/DotJoshJohnson/vscode-xml/issues"
|
||||
},
|
||||
"engines": {
|
||||
"vscode": "^1.22.2"
|
||||
"vscode": "^1.29.0"
|
||||
},
|
||||
"categories": [
|
||||
"Formatters",
|
||||
|
@ -36,6 +36,7 @@
|
|||
"onCommand:xmlTools.executeXQuery",
|
||||
"onCommand:xmlTools.formatAsXml",
|
||||
"onCommand:xmlTools.minifyXml",
|
||||
"onCommand:xmlTools.runXSLTTransform",
|
||||
"onLanguage:xml",
|
||||
"onLanguage:xquery",
|
||||
"onLanguage:xsl"
|
||||
|
@ -62,6 +63,10 @@
|
|||
{
|
||||
"command": "xmlTools.minifyXml",
|
||||
"title": "XML Tools: Minify XML"
|
||||
},
|
||||
{
|
||||
"command": "xmlTools.runXSLTTransform",
|
||||
"title": "XML Tools: Run XSLT Transformation"
|
||||
}
|
||||
],
|
||||
"configuration": {
|
||||
|
@ -250,11 +255,12 @@
|
|||
"@types/xmldom": "^0.1.29",
|
||||
"tslint": "^5.9.1",
|
||||
"typescript": "^2.6.1",
|
||||
"vscode": "^1.1.16"
|
||||
"vscode": "^1.1.26"
|
||||
},
|
||||
"dependencies": {
|
||||
"xmldom": "^0.1.27",
|
||||
"xpath": "0.0.27",
|
||||
"xqlint": "^0.4.1"
|
||||
"xqlint": "^0.4.1",
|
||||
"xslt-processor": "^0.11.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ export namespace commands {
|
|||
export const formatAsXml = "xmlTools.formatAsXml";
|
||||
export const getCurrentXPath = "xmlTools.getCurrentXPath";
|
||||
export const minifyXml = "xmlTools.minifyXml";
|
||||
export const runXSLTTransform = "xmlTools.runXSLTTransform";
|
||||
}
|
||||
|
||||
export namespace contextKeys {
|
||||
|
|
|
@ -11,6 +11,7 @@ import { XQueryLinter } from "./linting";
|
|||
import { XmlTreeDataProvider } from "./tree-view";
|
||||
import { evaluateXPath, getCurrentXPath } from "./xpath/commands";
|
||||
import { executeXQuery } from "./xquery-execution/commands";
|
||||
import { runXSLTTransform } from "./xslt";
|
||||
|
||||
import * as constants from "./constants";
|
||||
|
||||
|
@ -48,7 +49,7 @@ export function activate(context: ExtensionContext) {
|
|||
});
|
||||
|
||||
if (Configuration.enableXmlTreeViewCursorSync) {
|
||||
window.onDidChangeTextEditorSelection(x => {
|
||||
window.onDidChangeTextEditorSelection((x: any) => {
|
||||
if (x.kind === TextEditorSelectionChangeKind.Mouse && x.selections.length > 0) {
|
||||
treeView.reveal(treeViewDataProvider.getNodeAtPosition(x.selections[0].start));
|
||||
}
|
||||
|
@ -69,6 +70,11 @@ export function activate(context: ExtensionContext) {
|
|||
context.subscriptions.push(
|
||||
commands.registerTextEditorCommand(constants.commands.executeXQuery, executeXQuery)
|
||||
);
|
||||
|
||||
/* XSLT Transformation Features */
|
||||
context.subscriptions.push(
|
||||
commands.registerCommand(constants.commands.runXSLTTransform, runXSLTTransform)
|
||||
);
|
||||
}
|
||||
|
||||
export function deactivate() {
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import * as assert from "assert";
|
||||
import { FormattingOptions } from "vscode";
|
||||
|
||||
import { TestDataLoader } from "./test-utils/test-data-loader";
|
||||
|
||||
import { XmlFormatter, XmlFormattingOptions } from "../formatting";
|
||||
import { V2XmlFormatter } from "../formatting/formatters";
|
||||
import { readFileSync } from "fs";
|
||||
import { XSLTTransform } from "../xslt/xslt-transform";
|
||||
|
||||
describe("V2XmlFormatter", () => {
|
||||
|
||||
|
@ -91,6 +92,13 @@ describe("V2XmlFormatter", () => {
|
|||
it("should support mixed content", () => {
|
||||
testFormatter(xmlFormatter, options, "issue-200");
|
||||
});
|
||||
it("show transform XML to XSLT", () => {
|
||||
assert.doesNotThrow(() => {
|
||||
const xml = TestDataLoader.load("xslt-transform.xml");
|
||||
const xslt = TestDataLoader.load("xslt-transform.xsl");
|
||||
new XSLTTransform(xml, xslt).apply();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
|
48
src/test/test-data/xslt-transform.xml
Normal file
48
src/test/test-data/xslt-transform.xml
Normal file
|
@ -0,0 +1,48 @@
|
|||
<schedule>
|
||||
<week>
|
||||
<weektext>Orientation Week 1</weektext>
|
||||
<start_date>2018-07-30</start_date>
|
||||
<end_date>2018-08-11</end_date>
|
||||
<events>
|
||||
<event>
|
||||
<event_id>2317</event_id>
|
||||
<day>Sunday</day>
|
||||
<start_date_time>2018-08-06T07:30:00</start_date_time>
|
||||
<end_date_time>2018-08-06T12:00:00</end_date_time>
|
||||
<length>270</length>
|
||||
<event_title>Training</event_title>
|
||||
<short_name>Training</short_name>
|
||||
<instances>
|
||||
<instance>
|
||||
<start_date_time>2018-08-06T07:30:00</start_date_time>
|
||||
<end_date_time>2018-08-06T12:00:00</end_date_time>
|
||||
<room>See Course Website</room>
|
||||
<instructors>
|
||||
<instructor>... TBA</instructor>
|
||||
</instructors>
|
||||
</instance>
|
||||
</instances>
|
||||
</event>
|
||||
<event>
|
||||
<event_id>2316</event_id>
|
||||
<day>Sunday</day>
|
||||
<start_date_time>2018-08-06T08:10:00</start_date_time>
|
||||
<end_date_time>2018-08-06T12:00:00</end_date_time>
|
||||
<length>230</length>
|
||||
<event_title>Challenge Course</event_title>
|
||||
<short_name>Challenge</short_name>
|
||||
<instances>
|
||||
<instance>
|
||||
<start_date_time>2018-08-06T08:10:00</start_date_time>
|
||||
<end_date_time>2018-08-06T12:00:00</end_date_time>
|
||||
<room>See Course Website</room>
|
||||
<instructors>
|
||||
<instructor>Person One</instructor>
|
||||
<instructor>Person Two</instructor>
|
||||
</instructors>
|
||||
</instance>
|
||||
</instances>
|
||||
</event>
|
||||
</events>
|
||||
</week>
|
||||
</schedule>
|
72
src/test/test-data/xslt-transform.xsl
Normal file
72
src/test/test-data/xslt-transform.xsl
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
|
||||
<xsl:template match="/">
|
||||
|
||||
<div>
|
||||
|
||||
<table>
|
||||
|
||||
<xsl:for-each select="/schedule/week">
|
||||
<xsl:sort select="weektext"/>
|
||||
<tr><td colspan="4"><xsl:value-of select="weektext"/></td></tr>
|
||||
<xsl:for-each select="events/event">
|
||||
<xsl:sort select="events/event/start_date_time" type="datetime"/>
|
||||
<tr>
|
||||
<td>
|
||||
<xsl:value-of select="FormattedDate"/>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:value-of select="event_title"/>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:value-of select="length"/> minutes
|
||||
</td>
|
||||
<td>
|
||||
<a href="Activity?EventID={event_id}">details...</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<table>
|
||||
<xsl:for-each select="instances/instance">
|
||||
<tr>
|
||||
<td>
|
||||
<xsl:value-of select="start_date_time_formatted"/>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:value-of select="end_date_time_formatted"/>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:value-of select="room"/>
|
||||
</td>
|
||||
<td>
|
||||
<xsl:apply-templates select="instructors/instructor"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
</table>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</xsl:for-each>
|
||||
|
||||
</xsl:for-each>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="instructor">
|
||||
<xsl:text>, </xsl:text>
|
||||
<xsl:value-of select="."/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="instructor[1]">
|
||||
<xsl:value-of select="."/>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
|
@ -37,10 +37,10 @@ export class XmlTreeDataProvider implements TreeDataProvider<any> {
|
|||
const enableMetadata = Configuration.enableXmlTreeViewMetadata;
|
||||
const enableSync = Configuration.enableXmlTreeViewCursorSync;
|
||||
|
||||
const treeItem = new TreeItem(element.localName);
|
||||
const treeItem = new TreeItem((<Element>element).localName);
|
||||
|
||||
if (!this._xmlTraverser.isElement(element)) {
|
||||
treeItem.label = `${element.localName} = "${element.nodeValue}"`;
|
||||
treeItem.label = `${(<Element>element).localName} = "${element.nodeValue}"`;
|
||||
}
|
||||
|
||||
else if (enableMetadata) {
|
||||
|
|
2
src/xslt/index.ts
Normal file
2
src/xslt/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export * from "./xslt-apply";
|
||||
export * from "./xslt-transform";
|
1
src/xslt/schema.d.ts
vendored
Normal file
1
src/xslt/schema.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
declare module 'xslt-processor';
|
39
src/xslt/xslt-apply.ts
Normal file
39
src/xslt/xslt-apply.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
import { readFileSync } from "fs";
|
||||
import { window, workspace, ViewColumn } from "vscode";
|
||||
import { XSLTTransform } from "./xslt-transform";
|
||||
|
||||
export async function runXSLTTransform () {
|
||||
const xsltFile = await window.showOpenDialog(
|
||||
{
|
||||
canSelectFiles: true,
|
||||
canSelectFolders: false,
|
||||
canSelectMany: false,
|
||||
filters: {
|
||||
"XSLT" : ["xsl", "xslt"]
|
||||
}
|
||||
}
|
||||
);
|
||||
if (window.activeTextEditor !== undefined && xsltFile !== undefined) {
|
||||
const xml = window.activeTextEditor.document.getText();
|
||||
const xslt = readFileSync(xsltFile[0].fsPath).toString();
|
||||
try {
|
||||
const result = new XSLTTransform(xml, xslt).apply();
|
||||
const textDoc = await workspace.openTextDocument({
|
||||
content: result,
|
||||
language: "xml"
|
||||
});
|
||||
|
||||
window.showTextDocument(textDoc, ViewColumn.Beside);
|
||||
|
||||
const web = window.createWebviewPanel("transformPreview", "XSLT Results", ViewColumn.Beside, { });
|
||||
web.webview.html = result;
|
||||
|
||||
}
|
||||
catch (e) {
|
||||
window.showErrorMessage(e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
window.showErrorMessage("An error occurred while accessing the XML and/or XSLT source files.");
|
||||
}
|
||||
}
|
18
src/xslt/xslt-transform.ts
Normal file
18
src/xslt/xslt-transform.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
import { xmlParse, xsltProcess } from "xslt-processor";
|
||||
|
||||
export class XSLTTransform {
|
||||
private _xml: string;
|
||||
private _xslt: string;
|
||||
constructor(xml: string, xslt: string) {
|
||||
this._xml = xml;
|
||||
this._xslt = xslt;
|
||||
}
|
||||
public apply(): string {
|
||||
try {
|
||||
return xsltProcess(xmlParse(this._xml), xmlParse(this._xslt));
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue