Exemple #1
0
// actually produce (and possibly write) the final output
func (style *Stylesheet) constructOutput(output *xml.XmlDocument, options StylesheetOptions) (out string, err error) {
	//if not explicitly set, spec requires us to check for html
	outputType := style.OutputMethod
	if outputType == "" {
		outputType = "xml"
		root := output.Root()
		if root != nil && root.Name() == "html" && root.Namespace() == "" {
			outputType = "html"
		}
	}

	// construct DTD declaration depending on xsl:output settings
	docType := ""
	if style.doctypeSystem != "" {
		docType = "<!DOCTYPE "
		docType = docType + output.Root().Name()
		if style.doctypePublic != "" {
			docType = docType + fmt.Sprintf(" PUBLIC \"%s\"", style.doctypePublic)
		} else {
			docType = docType + " SYSTEM"
		}
		docType = docType + fmt.Sprintf(" \"%s\"", style.doctypeSystem)
		docType = docType + ">\n"
	}

	// create the XML declaration depending on xsl:output settings
	decl := ""
	if outputType == "xml" {
		if !style.OmitXmlDeclaration {
			decl = style.constructXmlDeclaration()
		}
		format := xml.XML_SAVE_NO_DECL | xml.XML_SAVE_AS_XML
		if options.IndentOutput || style.IndentOutput {
			format = format | xml.XML_SAVE_FORMAT
		}
		// we get slightly incorrect output if we call out.SerializeWithFormat directly
		// this seems to be a libxml bug; we work around it the same way libxslt does

		//TODO: honor desired encoding
		//  this involves decisions about supported encodings, strings vs byte slices
		//  we can sidestep a little if we enable option to write directly to file
		for cur := output.FirstChild(); cur != nil; cur = cur.NextSibling() {
			b, size := cur.SerializeWithFormat(format, nil, nil)
			if b != nil {
				out = out + string(b[:size])
			}
		}
		if out != "" {
			out = decl + docType + out + "\n"
		}
	}
	if outputType == "html" {
		out = docType
		b, size := output.ToHtml(nil, nil)
		out = out + string(b[:size])
	}
	if outputType == "text" {
		format := xml.XML_SAVE_NO_DECL
		for cur := output.FirstChild(); cur != nil; cur = cur.NextSibling() {
			b, size := cur.SerializeWithFormat(format, nil, nil)
			if b != nil {
				out = out + string(b[:size])
			}
		}
	}
	return
}