Skip to content

Commit

Permalink
Fix #67: Support basic XPath functions
Browse files Browse the repository at this point in the history
  • Loading branch information
sibprogrammer committed Jan 12, 2024
1 parent d95f6b6 commit 08f46d7
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 5 deletions.
27 changes: 26 additions & 1 deletion internal/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"github.com/PuerkitoBio/goquery"
"github.com/antchfx/xmlquery"
"github.com/antchfx/xpath"
"github.com/fatih/color"
"golang.org/x/net/html"
"golang.org/x/text/encoding/ianaindex"
Expand Down Expand Up @@ -214,13 +215,37 @@ func XPathQuery(reader io.Reader, writer io.Writer, query string, singleNode boo
if n := xmlquery.FindOne(doc, query); n != nil {
return printNodeContent(writer, n, options)
}
} else {
} else if options.WithTags {
for _, n := range xmlquery.Find(doc, query) {
err := printNodeContent(writer, n, options)
if err != nil {
return err
}
}
} else {
expr, _ := xpath.Compile(query)
val := expr.Evaluate(xmlquery.CreateXPathNavigator(doc))

switch typedVal := val.(type) {
case float64:
_, err = fmt.Fprintf(writer, "%.0f\n", typedVal)
case string:
_, err = fmt.Fprintf(writer, "%s\n", strings.TrimSpace(typedVal))
case *xpath.NodeIterator:
for typedVal.MoveNext() {
typedVal.Current()
_, err = fmt.Fprintf(writer, "%s\n", strings.TrimSpace(typedVal.Current().Value()))
if err != nil {
break
}
}
default:
return fmt.Errorf("unknown type error: %v", val)
}

if err != nil {
return err
}
}

return nil
Expand Down
10 changes: 6 additions & 4 deletions internal/utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,21 +102,23 @@ func TestXPathQuery(t *testing.T) {
type test struct {
input string
node bool
single bool
query string
result string
}

tests := []test{
{input: "formatted.xml", node: false, query: "//first_name", result: "John"},
{input: "unformatted8.xml", node: false, query: "//title", result: "Some Title"},
{input: "unformatted8.xml", node: true, query: "//title", result: "<title>Some Title</title>"},
{input: "formatted.xml", node: false, single: true, query: "//first_name", result: "John"},
{input: "unformatted8.xml", node: false, single: true, query: "//title", result: "Some Title"},
{input: "unformatted8.xml", node: true, single: true, query: "//title", result: "<title>Some Title</title>"},
{input: "unformatted8.xml", node: false, single: false, query: "count(//link)", result: "2"},
}

for _, testCase := range tests {
fileReader := getFileReader(path.Join("..", "..", "test", "data", "xml", testCase.input))
output := new(strings.Builder)
options := QueryOptions{WithTags: testCase.node, Indent: " "}
err := XPathQuery(fileReader, output, testCase.query, true, options)
err := XPathQuery(fileReader, output, testCase.query, testCase.single, options)
assert.Nil(t, err)
assert.Equal(t, testCase.result, strings.Trim(output.String(), "\n"))
}
Expand Down

0 comments on commit 08f46d7

Please sign in to comment.