I want to search through XML Using GetElementId .
I have an XML file with attributes associated with each element. Elements name may defer but each element will have unique Id.
For example:
<root>
<secondRoot>
<Person UniqueID='A112' Name='Fred'><FeMale>I am Female</FeMale></Person>
<Person UniqueID='A111'><Male>I am male</Male></Person>
<Person SSN='A222' Name='Tom'/>
<Customer id='A111'/>
<Customer id='A222334444'/>
<Team members='A222334444 A333445555'/>
<Random/>
</secondRoot>
</root>
In the above XML i have UniqueID attribute associated with several elements. I want to search elements with UniqueID attribute . Eventhough i tried using following DTD its not sufficient.
<!DOCTYPE root [
<!ELEMENT root ANY>
<!ATTLIST Person UniqueID ID #REQUIRED>
]>
The Problem is UniqueID may occur in several elements attribute list.
I need to avoid a situation which i have to declare every occurances of elements that have UniqueID attribute in DTD.
Can Anyone suggest any idea for that?
Thanks
Try using LINQ to XML, no need for DTD.
// XML data
var xml = "<root><secondRoot><Person UniqueID='A112' Name='Fred'><FeMale>I am Female</FeMale></Person><Person UniqueID='A111'><Male>I am male</Male></Person> <Person SSN='A222' Name='Tom'/> <Customer id='A111'/> <Customer id='A222334444'/> <Team members='A222334444 A333445555'/> <Random/></secondRoot></root>";
var doc = XDocument.Parse(xml);
// Get all nodes that have UniqueID
var nodes =
from element in doc.Descendants()
where element.Attribute("UniqueID") != null
select element;
The nodes list will contain all nodes that have the UniqueID attribute.
Related
How can I read the content of the childnotes using Xpath?
I have already tried this:
var xml = new XmlDocument();
xml.Load("server-status.xml");
var ns = new XmlNamespaceManager(xml.NameTable);
ns.AddNamespace("ns", "namespace");
var node = xml.SelectSingleNode("descendant::ns:server[ns:ip-address]", ns)
Console.WriteLine(node.InnerXml)
But I only get a string like this:
<ip-address>127.0.0.50</ip-address><name>Server 1</name><group>DATA</group>
How can I get the values individually?
Xml file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<server-status xmlns="namespace">
<server>
<ip-address>127.0.0.50</ip-address>
<name>Server 1</name>
<group>DATA</group>
</server>
</server-status>
You're using XML namespaces in XPath correctly.
However, your original XPath,
descendant::ns:server[ns:ip-address]
says to select all ns:server elements with ns:ip-address children.
If you wish to select the ns:ip-address children themselves, instead use
descendant::ns:server/ns:ip-address
Similarly, you could select ns:name or ns:group elements.
I have this snippt of XML
<unit class="xxx.xxx.xxx" id="382">
<customId>000</customId>
<description>kg</description>
<key>22452</key>
<Description>Kilogramm</Description>
</unit>
how to get the node 'unit' or parnet of the key element using the value of an element. For instance
i have the value of key element above [22452] and it's Uniqe inside the xml-File.
what i am trying to do getting value of customid [000] of that specific tag.
what i did:
var doc = new XmlDocument();
doc.Load(stream); // stream from xml-file
var key = doc.SelectSingleNode(//key/[text()='" + 22452+ "']"); // that i am not sure about it.
var customId = key.InnerText("customId");
For this kind of query you could either find the node and than navigate to the parent.
Or use XPath:
var unitElemnt = doc.SelectSingleNode("//unit[key = '22452']");
(Assuming I've remembered the XPath to match an element's text content correctly.)
This gets a reference to the <unit> element, by using a relative path to the <key> element in the predicate of the XPath expression.
Generally better to avoid // in XPath for performance, but would need full document structure to do that.
For this you can use Linq to Xml queries.
XElement units = XElement.Load("./Test.xml");
XElement unit = (from item in units.Descendants("unit")
where item.Element("key").Value == "22455"
select item).FirstOrDefault();
string customId = unit.Element("customId").Value;
supposing your xml file look like :
<?xml version="1.0" encoding="utf-8"?>
<units>
<unit class="xxx.xxx.xxx" id="385">
<customId>003</customId>
<description>kg</description>
<key>22455</key>
<Description>Kilogramm</Description>
</unit>
<unit class="xxx.xxx.xxx" id="386">
<customId>004</customId>
<description>kg</description>
<key>22456</key>
<Description>Kilogramm</Description>
</unit>
</units>
for more reading check Microsoft Linq to Xml Docs
First I want to find and select the PID"5678" from the <Tool>. With help of this PID, i want to find and select the ID"5678" from the <Parent>. The PID and the ID are the same value, but I have to find it from the <Tool> first.
At the moment I have following Code, to select the first PID. How can I "copy" this value and search with them the Attribute "ID"?
List<string> urls = xmldoc2.Descendants("PID").Select(x => x.Attribute("5678").Value).ToList();
<Tools>
<Tools>
<Tool>
<ID>1234</ID>
<PID>5678</PID>
<Name>Test</Name>
</Tool>
</Tools>
<Type>
<Parent>
<ID>5678</ID>
<PID>9999</PID>
<Name>Test2</Name>
</Parent>
</Type>
</Tools>
Notice that your Xml has multiple Root nodes - which does not work well.
So wrap it into single parent node (i.e. "Root" in below example)
Something of this sort should help you.
string xmlData = #"... Your Xml here....";
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlData);
var pidNodes = xmlDoc.SelectNodes("//Root/Tools/Tools/Tool/PID");
foreach(XmlNode node in pidNodes)
{
var typeNodeForPid = xmlDoc.SelectSingleNode(string.Format("//Root/Type/Parent[ID = '{0}']", node.InnerText));
}
Here is my xml file data
<Persons>
<Person>
<Name>john</Name>
</Person>
<Employee>
<Detail>
<Firstname>john</FirstName>
</Detail>
</Employee>
<Student>
<FullName>john</FullName>
</Student>
</Persons>
I want to replace "john" to "danny" in all places.
How can I do this in c# ?
One possible way using XDocument :
var doc = XDocument.Load("path_to_xml_file.xml");
//select all leaf elements having value equals "john"
var elementsToUpdate = doc.Descendants()
.Where(o => o.Value == "john" && !o.HasElements);
//update elements value
foreach(XElement element in elementsToUpdate)
{
element.Value = "danny";
}
//save the XML back as file
doc.Save("path_to_xml_file.xml");
Notice that XElement.Value contains all text nodes within the element, concatenated.
The significance of this is, for example, considering your XML as input, not only <Name> has value of "john" but also <Person>. But we only want to update the leaf elements not the ancestors.
*) I assumed you didn't really meant to tag the question by xmldocument so this answer using the newer XML API XDocument, though using XmlDocument is also possible.
I'm trying to work out why my xpath won't select the nodes I specificy
My xpath expression is //DefaultValue, so I expect all elements of name DefaultValue to be selected
My test file (cut down) is :
<?xml version="1.0" encoding="utf-8"?>
<SharedDataSet xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner" xmlns="http://schemas.microsoft.com/sqlserver/reporting/2010/01/shareddatasetdefinition">
<Description />
<DataSet Name="ddd">
<Query>
<DataSourceReference>xxx</DataSourceReference>
<DataSetParameters>
<DataSetParameter Name="p1">
<DefaultValue>baaaah</DefaultValue> <!-- this node should be selected eh? -->
</DataSetParameter>
<DataSetParameter Name="p2">
<DefaultValue>fooo</DefaultValue> <!-- this node should be selected too eh? -->
</DataSetParameter>
</DataSetParameters>
</Query>
</SharedDataSet>
Code is :
XmlNamespaceManager xn = new XmlNamespaceManager(new NameTable());
xn.AddNamespace("ns", "http://schemas.microsoft.com/sqlserver/reporting/2010/01/shareddatasetdefinition");
xn.AddNamespace("rd", "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner");
xn.AddNamespace("cl", "http://schemas.microsoft.com/sqlserver/reporting/2010/01/componentdefinition");
XDocument document = XDocument.Parse(reportBuffer, LoadOptions.PreserveWhitespace);
IEnumerable<XElement> elements = document.XPathSelectElements(xpath, xn);
at this point elements.Count() equals 0
Can anyone see what foolishness I present?
I can't seem to make the xml demons happy... :-(
The <DefaultValue> element is actually bound to the namespace http://schemas.microsoft.com/sqlserver/reporting/2010/01/shareddatasetdefinition.
The <SharedDataSet> document element has it declared without a prefix, so it is easy to miss. Since <DefaultValue> is a descendant, it inherits the namespace.
If you want to select the <DefaultValue> element you need to adjust your XPath:
//ns:DefaultValue