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鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
What's the best way to compute "#seq" when inserting new data into a MapSeq? #102
Comments
A bit of background -
Suppose I have the following XML doc.
Now I want to add another
Is that what I want? Or did I really want:
I suppose that I could just say that you get what you get based on the original sequence pattern in the XML object. The functionality is a cool idea, but I'll have to noodle on it a bit to see what might be possible without restricting the functionality to specific use cases. Of course, if the order of XML elements and subelements isn't meaningful, an |
What do you think of a mechanism to get/replace nodes at an XML level like the following? I think this could solve the use-case you describe (and would definitely help with mine) 馃檪 type ChildNode struct {
name string
data map[string]interface{} // Each of these could be a MapSeq
}
func (m MapSeq) GetSortedChildNodes() []ChildNode {
// Get all XML nodes at this level, sort, and return the list
}
func (m MapSeq) ReplaceChildNodes(childNodes []ChildNode) {
// Replace all XML nodes at this level with childNodes.
// Compute the values of #seq using the slice order
} Additionally, some helper functions like the following could help avoid dealing with #seq numbers at all: func (m MapSeq) SetAttr(key, value string) {
// Sets the value in the map for the attribute
// And computes the value of #seq as needed
} |
I can propose a PR with a real implementation if you think it would be helpful. Or if you'd rather noodle on it for a while and/or implement something yourself, that's fine, too 馃檪 |
I'd like to keep anything like this as minimal as possible, since it should also be available as a method for mxj.Map values for consistency. How about this?
Then, |
@clbanning that could work 馃檪. I think that solves my issue of "How do I insert new data". That doesn't help with this issue, though: #101 Maybe I was premature closing it 馃槄. Should I re-open that and we can discuss this particular issue over there? |
Hi @clbanning I have a temporally solution to add nested values on MapSeq on specific parent input:
output:
parentPath = "root.parent" func AddChildTextToXMLSeqParent(XMLdata *mxj.Map, parentPath, newChildTagName, tagContent string) error {
existingValues, err := XMLdata.ValuesForPath(parentPath)
if err != nil {
return err
}
var newParent = make(map[string]interface{})
maxseq := 0
for _, v := range existingValues {
cast, _ := v.(map[string]interface{})
for childComponent, childValues := range cast {
inside := make(map[string]interface{})
mapOfChild, _ := childValues.(map[string]interface{})
maxseq++
for key, value2 := range mapOfChild {
inside[key] = value2
newParent[childComponent] = inside
}
}
}
inside := make(map[string]interface{})
inside["#text"] = tagContent
inside["#seq"] = maxseq
newParent[newChildTagName] = inside
err = XMLdata.SetValueForPath(newParent, parentPath)
if err != nil {
return err
}
return nil
} |
Sorry for the belated response. I'd suggest folks use your (or davidkrauser's) code if it will work for them. However, as outlined in the Aug 19 comment, #102 (comment), such solutions will only perform in well-behaved cases. I had outlined a simple general solution similar to yours but which would default appended subelements to the end of the existing subelements of the "parent" using "#text" and without "#seq" map members. Such an approach would also allow similar functionality for mxj.Map values as well as mxj.MapSeq values. This whole direction feels a little convoluted right now, since |
I'm currently using
mxj.MapSeq
to modify XML documents, but I find adding new nodes cumbersome. It's likely that I'm doing something wrong, so I come to you for advice 馃槄Right now, when I want to add a new child node to some XML element, I assume that I need to figure out manually what the sequence number of that child node should be. To do so, I walk the
MapSeq
to find the largest number, then I add one to that. Is there a better way to do this?In code, that looks like:
The text was updated successfully, but these errors were encountered: