-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consistent Select/Query interface with xmlquery #7
Comments
My main concern with this change is that it changes the behaviour of jsonquery's As a result, this would be a breaking change. However, it would mean a consistent interface, and more predictable behaviour compared to the other query and select functions which all run a full query. |
I forget why no the below is incorrect json structure. {
"aa": "sss",
"aa": "sss"
} In json the |
TLDR: The main issue with this being doing so changes My main use case consideration was twofold; A work project involves a large configuration driven file processor, historically it worked only with xml files, but now adding JSON files. Having an abstract interface for both would mean the logic remains the same, but with different loaders, making the whole application simpler than putting type switches everywhere. To achieve this, the main case was queries like getting the elements of an array, or getting the presence of a keyword in sibling object properties. Such as for the test json:
running the query Given that Find/FindOne or Query/QueryAll are already implemented at the package level, and for xmlquery the methods just call them (passing the subject node as top) I'm unsure why the same pattern wasn't taken for this package? I've forked both packages and implemented a common interface, I'm currently looking at improving the test coverage in jsonquery, then I'll be doing a test in a real system to make sure it works as intended with real documents rather than simple unit tests. *Edited some typos |
You are right, I forgot the |
I'll be doing some testing tomorrow with the forked packages, so I'll report back if its working as intended, then we can make decisions on how to handle the breaking change to |
ok, mixed bag results, I created the interface type Selector interface {
// data retrieval
InnerText() string
// structure query
SelectElement(query string) Selector
SelectElements(query string) []Selector
Query(query string) (Selector, error)
QueryAll(query string) ([]Selector, error)
QuerySelector(query *xpath.Expr) Selector
QuerySelectorAll(query *xpath.Expr) []Selector
// ===================== //
// currently not working //
// ===================== //
// signature differs between packages
// OutputXML() string
// vs
// OutputXML(self bool) string
// only in jsonquery
// ChildNodes() []*Node
// could be added to xmlquery easily
// only in xmlquery
// SelectAttr(name string) string
// no analog in jsonquery
} As you can tell by the comments there were a few issues, the different signatures and differing functions could be overcome without too much issue, but the main issue; I'd forgotten that even if At this point, proxying the interface with a wrapper type is probably the best choice for my application, as a naïve example: func ConvertToSelector(doc *jsonquery.Node) common.Selector {
return selectorImpl{node: doc}
}
type selectorImpl struct {
node *jsonquery.Node
}
func (n selectorImpl) InnerText() string {
return n.node.InnerText()
}
func (n selectorImpl) SelectElements(query string) []common.Selector {
res := n.node.SelectElements(query)
result := make([]common.Selector, len(res))
for i := range res {
result[i] = selectorImpl{node: res[i]}
}
return result
}
// ... The new method versions of the selector functions still help with this, but this does detract somewhat from the motivation My current thought is to at least merge the forks and add the methods as they still have utility and can help other users, and improves test coverage. Any thoughts? |
Thans for your suggest, but This change will breaking the previous xmlquery and jsonquery package. xmlquery and jsonquery are independent packages, and both are depend on xpath package. |
In the sibling xmlquery package, the Node struct has public methods;
SelectElement(name string) *Node
andSelectElements(name string []*Node
jsonquery by comparison only has SelectElement.
Given both packages export the global function
Find
andFindOne
both can obviously be implemented for JSON, as they already are.I propose a change where jsonquery's
SelectElement
implementation mimics xmlquery's and internally callsFindOne
, and similarly addSelectElements
that internally callsFind
.To this end, both node types can be identified and used with an interface of
Allowing basic manipulation of both file types to only differ during load.
The alternative to this being using
Query
andQueryAll
to allow errors to be returned, instead of simply returning a nil result/panicking, or implementing both sets as methods in each package and allowing users to make the selection.Is this proposal sound and within the intended scope of this project?
If so I will make the changes and a pull request.
The text was updated successfully, but these errors were encountered: