问题
<location>
<hotspot name="name1" X="444" Y="518" />
<hotspot name="name2" X="542" Y="452" />
<hotspot name="name3" X="356" Y="15" />
</location>
I have a point variable and I need to select the node with its coordinates, then change an attribute value. I want to do something similar to:
let node = xmld.SelectSingleNode("/location/hotspot[@X='542' @Y='452']")
node.Attributes.[0].Value <- "new_name2"
but taking attributes value by a variable (variable_name.X / variable_name.Y).
回答1:
Personally I would use LINQ to XML:
var doc = XDocument.Load(...);
var node = doc.Root
.Elements("hotspot")
.Single(h => (int) h.Attribute("X") == x &&
(int) h.Attribute("Y") == y);
Note that you should use SingleOrDefault
if there may not be any matching elements, or First
/ FirstOrDefault
if there could be multiple matches.
Once you've found the right hotspot
node, you can set the attributes easily:
node.SetAttributeValue("X", newX);
node.SetAttributeValue("Y", newY);
回答2:
It was really easy. Supposing I want to modify the first attribute in my node:
let node = xmld.SelectSingleNode("/location/hotspot[@X='" + string(current.X) + "'] [@Y='" + string(current.Y) + "']")
node.Attributes.[0].Value <- v
where "current" is my variable ;)
回答3:
Maybe something like this will work:
// Tries to find the element corresponding to a specified point
let tryFindElementByPoint (xmlDoc : XmlDocument) point =
let pointElement =
point
||> sprintf "/location/hotspot[@X='%u' @Y='%u']"
|> xmlDoc.SelectSingleNode
match pointElement with
| null -> None
| x -> Some x
// Finds the element corresponding to a specified point, then updates an attribute value on the element.
let updatePointElement xmlDoc point (newValue : string) =
match tryFindElementByPoint xmlDoc point with
| None ->
point ||> failwithf "Couldn't find the XML element for the point (%u, %u)."
| Some node ->
// TODO : Make sure this updates the correct attribute!
node.Attributes.[0].Value <- newValue
回答4:
try this
//let node = xmld.SelectSingleNode("/location/hotspot[@X='542' and @Y='452']")
let query = sprintf "/location/hotspot[@X='%d' and @Y='%d']"
let node = xmld.SelectSingleNode(query 542 452)
回答5:
You cannot use an XPath expression to fill in more than one variable at a time. The only value returned by the XPath expression (or, on a more technical level, by the SelectSingleNode
that evaluates the XPath expression) is the Xml node identified by the expression.
Once you have the <hotspot>
element as a node object, you will have to use DOM APIs to read and write the attribute values, or possibly some utility routines to automatically transfer the attribute values to and from a strongly-typed data object.
来源:https://stackoverflow.com/questions/10963190/select-xml-node-by-attribute-value