コード例 #1
0
ファイル: stylesheet_test.go プロジェクト: xet7/ratago
// sample usage for parse stylesheet
func ExampleParseStylesheet() {
	//parse the stylesheet
	style, _ := xml.ReadFile("testdata/test.xsl", xml.StrictParseOption)
	stylesheet, _ := ParseStylesheet(style, "testdata/test.xsl")

	//process the input
	input, _ := xml.ReadFile("testdata/test.xml", xml.StrictParseOption)
	output, _ := stylesheet.Process(input, StylesheetOptions{false, nil})
	fmt.Println(output)
}
コード例 #2
0
ファイル: context.go プロジェクト: xet7/ratago
func (context *ExecutionContext) FetchInputDocument(loc string, relativeToSource bool) (doc *xml.XmlDocument) {
	//create the map if needed
	if context.InputDocuments == nil {
		context.InputDocuments = make(map[string]*xml.XmlDocument)
	}

	// rely on caller to tell us how to resolve relative paths
	base := ""
	if relativeToSource {
		base, _ = filepath.Abs(filepath.Dir(context.Source.Uri()))
	} else {
		base, _ = filepath.Abs(filepath.Dir(context.Style.Doc.Uri()))
	}
	resolvedLoc := filepath.Join(base, loc)

	//if abspath in map return existing document
	doc, ok := context.InputDocuments[resolvedLoc]
	if ok {
		return
	}

	//else load the document and add to map
	doc, e := xml.ReadFile(resolvedLoc, xml.StrictParseOption)
	if e != nil {
		fmt.Println(e)
		return
	}
	context.InputDocuments[resolvedLoc] = doc
	return
}
コード例 #3
0
ファイル: stylesheet_test.go プロジェクト: xet7/ratago
// Helper where actual checking occurs
func runXslTest(t *testing.T, xslFile, inputXmlFile, outputXmlFile string) bool {
	style, _ := xml.ReadFile(xslFile, xml.StrictParseOption)
	input, _ := xml.ReadFile(inputXmlFile, xml.StrictParseOption)
	outData, _ := ioutil.ReadFile(outputXmlFile)
	expected := string(outData)
	stylesheet, _ := ParseStylesheet(style, xslFile)
	testOptions := StylesheetOptions{false, nil}
	output, _ := stylesheet.Process(input, testOptions)
	if output != expected {
		t.Error(xslFile, "failed")
		fmt.Println("---- EXPECTED  ", xslFile, "----")
		fmt.Println(expected)
		fmt.Println("---- ACTUAL  ", xslFile, "----")
		fmt.Println(output)
		return false
	}
	return true
}
コード例 #4
0
ファイル: ratago.go プロジェクト: xet7/ratago
func main() {
	flag.Usage = usage
	flag.Parse()
	if flag.NArg() < 2 {
		usage()
		return
	}
	//set some prefs based on flags
	xslfile := flag.Arg(0)
	inxml := flag.Arg(1)

	style, err := xml.ReadFile(xslfile, xml.StrictParseOption)
	if err != nil {
		fmt.Println(err)
		return
	}

	doc, err := xml.ReadFile(inxml, xml.StrictParseOption)
	if err != nil {
		fmt.Println(err)
		return
	}

	//TODO: register some extensions (EXSLT, testing, debug)
	//TODO: process XInclude if enabled
	stylesheet, err := xslt.ParseStylesheet(style, xslfile)
	if err != nil {
		fmt.Println(err)
		return
	}

	options := xslt.StylesheetOptions{*indent, nil}

	output, err := stylesheet.Process(doc, options)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(output)
}
コード例 #5
0
ファイル: transform.go プロジェクト: philr/feedtr
// Creates an xlstTransform from file specified by path.
func newXsltTransform(path string) (*xsltTransform, error) {
	doc, err := xml.ReadFile(path, xml.StrictParseOption)

	if err != nil {
		return nil, err
	}

	stylesheet, err := xslt.ParseStylesheet(doc, path)

	if err != nil {
		doc.Free()
		return nil, err
	}

	result := new(xsltTransform)
	result.stylesheet = stylesheet
	return result, nil
}
コード例 #6
0
ファイル: transform.go プロジェクト: philr/feedtr
// Runs the transformation on the given input, returning an output as a byte
// slice.
func (transform *xsltTransform) Process(input []byte) ([]byte, error) {
	// gokogiri can automatically determine the encoding when parsing a
	// file, but not when loading from memory. Save to a temporary file until
	// a better method can be found.

	file, err := ioutil.TempFile(os.TempDir(), "ftxlstin")

	if err != nil {
		return nil, err
	}

	defer os.Remove(file.Name())

	_, err = file.Write(input)

	if err != nil {
		return nil, err
	}

	doc, err := xml.ReadFile(file.Name(), xml.StrictParseOption)

	if err != nil {
		return nil, err
	}

	defer doc.Free()

	options := xslt.StylesheetOptions{false, nil}
	output, err := transform.stylesheet.Process(doc, options)

	if err != nil {
		return nil, err
	}

	return []byte(output), nil
}
コード例 #7
0
ファイル: stylesheet.go プロジェクト: xet7/ratago
// Here we iterate through the children; this has been moved to its own function
// to facilitate the implementation of xsl:include (where we want the children to
// be treated as if they were part of the calling stylesheet)
func (style *Stylesheet) parseChildren(root xml.Node, fileuri string) (err error) {
	//iterate through children
	for cur := root.FirstChild(); cur != nil; cur = cur.NextSibling() {
		//skip blank nodes
		if IsBlank(cur) {
			continue
		}

		//skip comment nodes
		if cur.NodeType() == xml.XML_COMMENT_NODE {
			continue
		}

		//handle templates
		if IsXsltName(cur, "template") {
			style.ParseTemplate(cur)
			continue
		}

		if IsXsltName(cur, "variable") {
			style.RegisterGlobalVariable(cur)
			continue
		}

		if IsXsltName(cur, "key") {
			name := cur.Attr("name")
			use := cur.Attr("use")
			match := cur.Attr("match")
			k := &Key{make(map[string]xml.Nodeset), use, match}
			style.Keys[name] = k
			continue
		}

		//TODO: this is cheating. Also note global params can have their
		// value overwritten
		if IsXsltName(cur, "param") {
			style.RegisterGlobalVariable(cur)
			continue
		}

		if IsXsltName(cur, "attribute-set") {
			style.RegisterAttributeSet(cur)
			continue
		}

		if IsXsltName(cur, "include") {
			//check for recursion, multiple includes
			loc := cur.Attr("href")
			base := path.Dir(fileuri)
			loc = path.Join(base, loc)
			_, already := style.includes[loc]
			if already {
				panic("Multiple include detected of " + loc)
			}
			style.includes[loc] = true

			//load the stylesheet
			doc, e := xml.ReadFile(loc, xml.StrictParseOption)
			if e != nil {
				fmt.Println(e)
				err = e
				return
			}
			//_, _ = ParseStylesheet(doc, loc)
			//update the including stylesheet
			e = style.parseChildren(doc.Root(), loc)
			if e != nil {
				fmt.Println(e)
				err = e
				return
			}
			continue
		}

		if IsXsltName(cur, "import") {
			//check for recursion, multiple includes
			loc := cur.Attr("href")
			base := path.Dir(fileuri)
			loc = path.Join(base, loc)
			_, already := style.includes[loc]
			if already {
				panic("Multiple include detected of " + loc)
			}
			style.includes[loc] = true
			//increment import; new style context
			doc, _ := xmlReadFile(loc)
			_import, _ := ParseStylesheet(doc, loc)
			style.Imports.PushFront(_import)
			continue
		}

		if IsXsltName(cur, "output") {
			cdata := cur.Attr("cdata-section-elements")
			if cdata != "" {
				style.CDataElements = strings.Fields(cdata)
			}
			style.OutputMethod = cur.Attr("method")
			omit := cur.Attr("omit-xml-declaration")
			if omit == "yes" {
				style.OmitXmlDeclaration = true
			}
			indent := cur.Attr("indent")
			if indent == "yes" {
				style.IndentOutput = true
			}
			standalone := cur.Attr("standalone")
			if standalone == "yes" {
				style.Standalone = true
			}
			encoding := cur.Attr("encoding")
			if encoding != "" && encoding != "utf-8" {
				//TODO: emit a warning if we do not support the encoding
				// if unsupported, leave blank to output default UTF-8
				style.DesiredEncoding = encoding
			}
			style.doctypeSystem = cur.Attr("doctype-system")
			style.doctypePublic = cur.Attr("doctype-public")
			continue
		}

		if IsXsltName(cur, "strip-space") {
			el := cur.Attr("elements")
			if el != "" {
				style.StripSpace = strings.Fields(el)
			}
			continue
		}

		if IsXsltName(cur, "preserve-space") {
			el := cur.Attr("elements")
			if el != "" {
				style.PreserveSpace = strings.Fields(el)
			}
			continue
		}

		if IsXsltName(cur, "namespace-alias") {
			stylens := cur.Attr("stylesheet-prefix")
			resns := cur.Attr("result-prefix")
			style.NamespaceAlias[stylens] = resns
			continue
		}

		if IsXsltName(cur, "decimal-format") {
			fmt.Println("GLOBAL TODO ", cur.Name())
			continue
		}
	}
	return
}