Select XML node by attribute value

旧时模样 提交于 2019-12-24 03:07:06

问题


<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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!