R: Insert the node into the XML tree in a specific location

Data

I have an xml file with a structure like this (big example showing the required flexibility):







< br />





< someContent/>

















Specifically, The size of any tag node is unknown, the number of attributes of all tag nodes is not equal, and the value of the attribute is not unique.
However, what I know is that the value of the searchA attribute is unique. In addition, only the tag node You can include an attribute named searchA, and all attributes except the top-level node are included.

Before

I first parse this document using the XML package with the function xmlTreeParse() And store the root node. Then, I use newXMLNode() to create a new node.

xmlfile = xmlTreeParse(filename, useInternalNodes = TRUE)
xmltop = xmlRoot(xmlfile )
newNode = newXMLNode(name = "newlyCreatedNode")

Target

My goal is to use my newly created newNode as a node with a specific value (e.g. “sth23 “) into the searchA attribute.
So in this case I want the result to look like this (note the near the bottom):

 































Basically, in this case, addChildren( xmltop [[1]] [[3]] [[1]],kids = list(newNode)) to get the results I want. Of course I don’t want to specify [[1]] [[3]] [[1]] .

What have I tried

I can use xmlElementsByTagName() to get a list of all related nodes, and use xmlAttrs() to get all attributes. I can even get a logical index vector, It gives me the correct location.

listOfNodes = xmlElementsByTagName(el = xmltop, "tag", recursive = T)
attributeList = lapply(listOfNodes, FUN = function (x) xmlAttrs(x))
indexVector = sapply(attributeList, FUN = function(x) x["searchA"] == "sth23")
indexVector[is.na(indexVector)] = FALSE
listOfNodes[indexVector]

What I don’t know is how to use this information to insert my nodes into the tree in the correct position.
listOfNodes [indexVector] gives me the correct Node, but it is now a list instead of nodes where I can use addChildren().
Even if I somehow manage to map the indexVector and the xmlSize() of all nodes to the correct index that I can use directly on xmltop , I still encounter the problem of a variable number of double brackets (xmltop [[1]] [[3]] vs xmltop [[1]] [[2]] [[1]]).< /p>

I also tried several other functions of the XML package, including xmlApply, getNodeLocation and getNodeSet, but they don’t seem to help.

I haven’t really tried it

I really don’t understand the difference between xmlTreeParse(), xmlInternalTreeParse() and xmlTreeParse(useInternalNodes = T), I can’t wrap my head in XPath, so I didn’t try to use it.

Anything useful Any pointers would be greatly appreciated.

What is the reason for my confusion? The help page of xmlElementsByTagName. It says:

“The addition of the recursive argument makes this function behave like the getElementsByTagName in other language APIs such as Java, C\#. However, one should be careful to understand that in those languages, one would get back a set of node objects. These nodes have references to their parents and children . Therefore one can navigate the tree from each node, find its relations, etc. In the current version of this package (and for the forseeable future), the node set is a “copy” of the nodes in the original tree. And these have no facilities for finding their siblings or parent.”

This makes me think that the function returns a list of copies instead of a reference to the node itself.
If you use xmlTreeParse set to FALSE () The flag of the function useInternalNodes parses xml, which may be the case, but if it is set to TRUE when parsing, the list returned by xmlElementsByTagName() seems to contain actual references.
These can be easily manipulated using, for example, addChildren() .

In short, the simple solution to my problem is:

addChildren(listOfNodes[indexVector], kids = list(newNode)) 

Data

I have an xml file with a structure like this (big example showing the required flexibility):
































Specifically, the size of any marked node is unknown, The number of attributes of all tag nodes is not equal, and the value of the attribute is not unique.
However, what I know is that the value of the searchA attribute is unique. In addition, only the tag node can contain an attribute named searchA, except All attributes other than the top-level node are included.

Before

I first parse this document using the XML package with the function xmlTreeParse() and store the root node. Then, I use newXMLNode ()Create a new node.

xmlfile = xmlTreeParse(filename, useInternalNodes = TRUE)
xmltop = xmlRoot(xmlfile)
newNode = newXMLNode(name = "newlyCreatedNode")

Target

My goal is to insert my newly created newNode as a child node of a node with a specific value (e.g. “sth23”) into the searchA attribute.< br>So in this case I want the result to look like this (note the near the bottom):























< someContent/>









Basically, in this case, addChildren(xmltop [[1]] [[3]] [[1] ],kids = list(newNode)) to get the result I want. Of course I don’t want to specify [[1]] [[3]] [[1]].

What did I try

I can use xmlElementsByTagName() to get a list of all related nodes, and use xmlAttrs() to get all attributes. I can even get a logical index vector, which gives me the correct position.

< /p>

listOfNodes = xmlElementsByTagName(el = xmltop, "tag", recursive = T)
attributeList = lapply(listOfNodes, FUN = function(x) xmlAttrs(x))
indexVector = sapply (attributeList, FUN = function(x) x["searchA"] == "sth23")
indexVector[is.na(indexVector)] = FALSE
listOfNodes[indexVector]

What I don’t know is how to use this information to insert my node into the tree in the correct position.
listOfNodes [indexVector] gives me the correct node, but it is now a list instead of that I can use addChildren( ) Node.
Even if I somehow manage to map the indexVector and the xmlSize() of all nodes to the correct index that I can use directly on xmltop, I still encounter the variable number of double brackets problem (xmltop [[1]] [[3]] vs xmltop [[1]] [[2]] [[1]]).

I also tried several other functions of the XML package, including xmlApply ,getNodeLoca tion and getNodeSet, but they don’t seem to help.

I haven’t really tried it

I really don’t understand xmlTreeParse(), xmlInternalTreeParse() and xmlTreeParse(useInternalNodes = T) The difference, I can’t wrap my head in XPath, so I didn’t try to use it.

Any useful pointers would be greatly appreciated.

The reason for my confusion? The help page of xmlElementsByTagName. It says:

“The addition of the recursive argument makes this function behave like the getElementsByTagName in other language APIs such as Java, C\#. However, one should be careful to understand that in those languages, one would get back a set of node objects. These nodes have references to their parents and children . Therefore one can navigate the tree from each node, find its relations, etc. In the current version of this package (and for the forseeable future), the node set is a “copy” of the nodes in the original tree. And these have no facilities for finding their siblings or parent.”

This makes me think that the function returns a list of copies instead of a reference to the node itself.
If you use xmlTreeParse set to FALSE () The flag of the function useInternalNodes parses xml, which may be the case, but if it is set to TRUE when parsing, the list returned by xmlElementsByTagName() seems to contain actual references.
These can be easily manipulated using, for example, addChildren() .

In short, the simple solution to my problem is:

addChildren(listOfNodes[indexVector], kids = list(newNode)) 

Leave a Comment

Your email address will not be published.