//Implementation of document() from XSLT spec func XsltDocumentFn(context xpath.VariableScope, args []interface{}) interface{} { if len(args) < 1 { return nil } c := context.(*ExecutionContext) switch doc := args[0].(type) { case string: if doc == "" { nodeset := xml.Nodeset{c.Style.Doc} return nodeset.ToPointers() } input := c.FetchInputDocument(doc, false) if input != nil { nodeset := xml.Nodeset{input} return nodeset.ToPointers() } return nil case []unsafe.Pointer: n := xml.NewNode(doc[0], nil) location := n.Content() input := c.FetchInputDocument(location, true) if input != nil { nodeset := xml.Nodeset{input} return nodeset.ToPointers() } fmt.Println("DOCUMENT", location) } return nil }
func EXSLTnodeset(context xpath.VariableScope, args []interface{}) interface{} { if len(args) < 1 { return nil } c := context.(*ExecutionContext) nodes := args[0] switch v := nodes.(type) { case []unsafe.Pointer: if len(v) == 0 { return nil } fauxroot := c.Output.CreateElementNode("VARIABLE") for _, node := range v { n := xml.NewNode(node, nil) fauxroot.AddChild(n) } out := xml.Nodeset{fauxroot} return out.ToPointers() default: out := fmt.Sprintf("%v", v) fmt.Println("invalid argument to exslt:nodeset", out) } return nodes }
func (context *ExecutionContext) EvalXPathAsNodeset(xmlNode xml.Node, data interface{}) (result xml.Nodeset, err error) { _, err = context.EvalXPath(xmlNode, data) if err != nil { return nil, err } nodePtrs, err := context.XPathContext.ResultAsNodeset() if err != nil { return nil, err } var output xml.Nodeset for _, nodePtr := range nodePtrs { output = append(output, xml.NewNode(nodePtr, xmlNode.MyDocument())) } result = output return }
// util function because we can't assume we're actually getting a string func argValToString(val interface{}) (out string) { if val == nil { return } switch v := val.(type) { case string: return v case []unsafe.Pointer: if len(v) == 0 { return } n := xml.NewNode(v[0], nil) out = n.Content() default: out = fmt.Sprintf("%v", v) } return }
func (context *ExecutionContext) EvalXPath(xmlNode xml.Node, data interface{}) (result interface{}, err error) { switch data := data.(type) { case string: if xpathExpr := xpath.Compile(data); xpathExpr != nil { defer xpathExpr.Free() result, err = context.EvalXPath(xmlNode, xpathExpr) } else { err = errors.New("cannot compile xpath: " + data) } case []byte: result, err = context.EvalXPath(xmlNode, string(data)) case *xpath.Expression: xpathCtx := context.XPathContext xpathCtx.SetResolver(context) err := xpathCtx.Evaluate(xmlNode.NodePtr(), data) if err != nil { return nil, err } rt := xpathCtx.ReturnType() switch rt { case xpath.XPATH_NODESET, xpath.XPATH_XSLT_TREE: nodePtrs, err := xpathCtx.ResultAsNodeset() if err != nil { return nil, err } var output []xml.Node for _, nodePtr := range nodePtrs { output = append(output, xml.NewNode(nodePtr, xmlNode.MyDocument())) } result = output case xpath.XPATH_NUMBER: result, err = xpathCtx.ResultAsNumber() case xpath.XPATH_BOOLEAN: result, err = xpathCtx.ResultAsBoolean() default: result, err = xpathCtx.ResultAsString() } default: err = errors.New("Strange type passed to ExecutionContext.EvalXPath") } return }