diff options
| author | Michael Williamson <mike@zwobble.org> | 2018-01-16 22:33:06 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2018-01-16 22:33:06 +0000 |
| commit | d3b5060cdd565e6d7454c75f8de68987be9ed2c8 (patch) | |
| tree | 8a5a8253ff4f32e3ad87d1b71793fbf4a3be7d34 | |
| parent | cc1b5b19480befc5611a469424a5ae16f9ebce21 (diff) | |
Read document XML path from _rels/.rels
| -rw-r--r-- | lib/docx/docx-reader.js | 28 | ||||
| -rw-r--r-- | test/docx/docx-reader.tests.js | 29 |
2 files changed, 51 insertions, 6 deletions
diff --git a/lib/docx/docx-reader.js b/lib/docx/docx-reader.js index 54f2a3b..67ff11d 100644 --- a/lib/docx/docx-reader.js +++ b/lib/docx/docx-reader.js @@ -24,6 +24,7 @@ function read(docxFile, input) { contentTypes: readContentTypesFromZipFile(docxFile), numbering: readNumberingFromZipFile(docxFile), styles: readStylesFromZipFile(docxFile), + fileRelationships: readFileRelationships(docxFile), docxFile: docxFile, files: new Files(input.path ? path.dirname(input.path) : null) }).also(function(result) { @@ -59,8 +60,9 @@ function read(docxFile, input) { }) }; }).then(function(result) { - return readXmlFileWithBody("word/document.xml", result, function(bodyReader, xml) { - if (xml) { + var documentFilename = findDocumentFilename(docxFile, result.fileRelationships); + if (documentFilename) { + return readXmlFileWithBody(documentFilename, result, function(bodyReader, xml) { return result.notes.flatMap(function(notes) { return result.comments.flatMap(function(comments) { var reader = new DocumentXmlReader({ @@ -71,13 +73,21 @@ function read(docxFile, input) { return reader.convertXmlToDocument(xml); }); }); - } else { - throw new Error("Could not find word/document.xml in ZIP file. Are you sure this is a valid .docx file?"); - } - }); + }); + } else { + throw new Error("Could not find word/document.xml in ZIP file. Are you sure this is a valid .docx file?"); + } }); } +function findDocumentFilename(docxFile, relationships) { + var targets = ["word/document.xml"].concat(relationships.findTargetsByType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument")); + var validTargets = targets.filter(function(target) { + return docxFile.exists(target); + }); + return validTargets[0]; +} + function xmlFileReader(options) { return function(zipFile) { return readXmlFromZipFile(zipFile, options.filename) @@ -133,3 +143,9 @@ var readStylesFromZipFile = xmlFileReader({ readElement: stylesReader.readStylesXml, defaultValue: stylesReader.defaultStyles }); + +var readFileRelationships = xmlFileReader({ + filename: "_rels/.rels", + readElement: relationshipsReader.readRelationships, + defaultValue: relationshipsReader.defaultValue +}); diff --git a/test/docx/docx-reader.tests.js b/test/docx/docx-reader.tests.js index 283d03a..a25d76e 100644 --- a/test/docx/docx-reader.tests.js +++ b/test/docx/docx-reader.tests.js @@ -2,6 +2,7 @@ var assert = require("assert"); var docxReader = require("../../lib/docx/docx-reader"); var documents = require("../../lib/documents"); +var xml = require("../../lib/xml"); var testing = require("../testing"); var test = require("../test")(module); @@ -38,3 +39,31 @@ test("hyperlink hrefs are read from relationships file", function() { assert.equal(hyperlink.children.length, 1); }); }); + +var relationshipNamespaces = { + "r": "http://schemas.openxmlformats.org/package/2006/relationships" +}; + +test("when document.xml is not present then document is found using _rels/.rels", function() { + var relationships = xml.element("r:Relationships", {}, [ + xml.element("r:Relationship", { + "Type": "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument", + "Target": "word/document2.xml" + }) + ]); + + var docxFile = createFakeDocxFile({ + "word/document2.xml": testData("simple/word/document.xml"), + "_rels/.rels": xml.writeString(relationships, relationshipNamespaces) + }); + var expectedDocument = documents.Document([ + documents.Paragraph([ + documents.Run([ + documents.Text("Hello.") + ]) + ]) + ]); + return docxReader.read(docxFile).then(function(result) { + assert.deepEqual(expectedDocument, result.value); + }); +}); |
