Browse Source

Put all the nasty namespace hacks in one function.

Geoffrey J. Teale 10 years ago
parent
commit
68024311d5
2 changed files with 19 additions and 15 deletions
  1. 17 13
      file.go
  2. 2 2
      file_test.go

+ 17 - 13
file.go

@@ -151,10 +151,22 @@ func (f *File) makeWorkbook() xlsxWorkbook {
 	return workbook
 }
 
-//For importing excel at SAS, WorkkBook.SheetViews.Sheet's node string(including two attribute xmlns:relationships, relationships:id)
-//`xmlns:relationships="http://schemas.openxmlformats.org/officeDocument/2006/relationships" relationships:id` should be replaced to `r:id`
-func replacingWorkbookSheetId(workbookMarshal string) string {
-	return strings.Replace(workbookMarshal, `xmlns:relationships="http://schemas.openxmlformats.org/officeDocument/2006/relationships" relationships:id`, `r:id`, -1)
+// Some tools that read XLSX files have very strict requirements about
+// the structure of the input XML.  In particular both Numbers on the Mac
+// and SAS dislike inline XML namespace declarations, or namespace
+// prefixes that don't match the ones that Excel itself uses.  This is a
+// problem because the Go XML library doesn't multiple namespace
+// declarations in a single element of a document.  This function is a
+// horrible hack to fix that after the XML marshalling is completed.
+func replaceRelationshipsNameSpace(workbookMarshal string) string {
+	newWorkbook := strings.Replace(workbookMarshal, `xmlns:relationships="http://schemas.openxmlformats.org/officeDocument/2006/relationships" relationships:id`, `r:id`, -1)
+	// Dirty hack to fix issues #63 and #91; encoding/xml currently
+	// "doesn't allow for additional namespaces to be defined in the
+	// root element of the document," as described by @tealeg in the
+	// comments for #63.
+	oldXmlns := `<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">`
+	newXmlns := `<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">`
+	return strings.Replace(newWorkbook, oldXmlns, newXmlns, 1)
 }
 
 // Construct a map of file name to XML content representing the file
@@ -212,20 +224,12 @@ func (f *File) MarshallParts() (map[string]string, error) {
 	if err != nil {
 		return parts, err
 	}
-	workbookMarshal = replacingWorkbookSheetId(workbookMarshal)
+	workbookMarshal = replaceRelationshipsNameSpace(workbookMarshal)
 	parts["xl/workbook.xml"] = workbookMarshal
 	if err != nil {
 		return parts, err
 	}
 
-	// Make it work with Mac Numbers.
-	// Dirty hack to fix issues #63 and #91; encoding/xml currently
-	// "doesn't allow for additional namespaces to be defined in the root element of the document,"
-	// as described by @tealeg in the comments for #63.
-	oldXmlns := `<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">`
-	newXmlns := `<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">`
-	parts["xl/workbook.xml"] = strings.Replace(parts["xl/workbook.xml"], oldXmlns, newXmlns, 1)
-
 	parts["_rels/.rels"] = TEMPLATE__RELS_DOT_RELS
 	parts["docProps/app.xml"] = TEMPLATE_DOCPROPS_APP
 	// TODO - do this properly, modification and revision information

+ 2 - 2
file_test.go

@@ -256,10 +256,10 @@ func (l *FileSuite) TestMarshalWorkbook(c *C) {
 		State:   "visible"}
 
 	expectedWorkbook := `<?xml version="1.0" encoding="UTF-8"?>
-<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><fileVersion appName="Go XLSX"></fileVersion><workbookPr showObjects="all" date1904="false"></workbookPr><workbookProtection></workbookProtection><bookViews><workbookView showHorizontalScroll="true" showVerticalScroll="true" showSheetTabs="true" tabRatio="204" windowHeight="8192" windowWidth="16384" xWindow="0" yWindow="0"></workbookView></bookViews><sheets><sheet name="MyFirstSheet" sheetId="1" r:id="rId1" state="visible"></sheet><sheet name="MySecondSheet" sheetId="2" r:id="rId2" state="visible"></sheet></sheets><definedNames></definedNames><calcPr iterateCount="100" refMode="A1" iterateDelta="0.001"></calcPr></workbook>`
+<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><fileVersion appName="Go XLSX"></fileVersion><workbookPr showObjects="all" date1904="false"></workbookPr><workbookProtection></workbookProtection><bookViews><workbookView showHorizontalScroll="true" showVerticalScroll="true" showSheetTabs="true" tabRatio="204" windowHeight="8192" windowWidth="16384" xWindow="0" yWindow="0"></workbookView></bookViews><sheets><sheet name="MyFirstSheet" sheetId="1" r:id="rId1" state="visible"></sheet><sheet name="MySecondSheet" sheetId="2" r:id="rId2" state="visible"></sheet></sheets><definedNames></definedNames><calcPr iterateCount="100" refMode="A1" iterateDelta="0.001"></calcPr></workbook>`
 	output, err := xml.Marshal(workbook)
 	c.Assert(err, IsNil)
-	outputStr := replacingWorkbookSheetId(string(output))
+	outputStr := replaceRelationshipsNameSpace(string(output))
 	stringOutput := xml.Header + outputStr
 	c.Assert(stringOutput, Equals, expectedWorkbook)
 }