i am beginer and i write this code and can't send ENTER click from webbrowser component on C#:
private void start_submit_Click(object sender, EventArgs e)
{
XmlDocument xdoc = new XmlDocument();
xdoc.Load("settings.xml");
foreach (System.Xml.XmlNode node in xdoc.SelectNodes("//site"))
{
foreach (System.Xml.XmlNode child in node)
{
if (child.Attributes["todo"].Value.ToString() == "navigate")
{
navigate(url_string);
}
else if (child.Attributes["todo"].Value.ToString() == "checkbox")
{
HtmlElementCollection es = webBrowser1.Document.GetElementsByTagName("input");
HtmlElement ele0 = es[1];
ele0.SetAttribute("checked", "true");
}
else if (child.Attributes["todo"].Value.ToString() == "pressbutton")
{
HtmlElementCollection es = webBrowser1.Document.GetElementsByTagName("input");
if (es != null && es.Count != 0)
{
HtmlElement ele = es[5];
ele.ScrollIntoView(true);
ele.Focus();
SendKeys.Send("{ENTER}");
}
}
else if (child.Attributes["todo"].Value.ToString() == "wait")
{
MessageBox.Show("waiting...");
}
}
}
}
and settings.xml file:
<?xml version="1.0" encoding="utf-8" ?>
<data>
<site num="1" name="http://www.clantemplates.com" pr="5">
<step num="1" todo="navigate" value_todo="http://www.clantemplates.com/forums/register.php" value_2_todo="none">navigating</step>
<step num="2" todo="checkbox" value_todo="true" value_2_todo="8">checking checkbox</step>
<step num="3" todo="pressbutton" value_todo="enter" value_2_todo="9">pressing button</step>
<step num="4" todo="wait" value_todo="" value_2_todo="">waiting for other click</step>
</site>
</data>
without this piece ENTER sends succesfully
else if (child.Attributes["todo"].Value.ToString() == "wait")
{
MessageBox.Show("waiting...");
}
with piece - no
how to solve?
Thanks!
Solved, i do that with:
HtmlElementCollection es = webBrowser1.Document.GetElementsByTagName("input");
HtmlElement ele = es[5];
ele.InvokeMember("Click");
Related
<TestSuite name="TestSuite1">
<TestCase name="TestCase1" UID="1" State="1" DataSourceId="1">
<TestModule name="Recording1" State="Checked" UID="1">
</TestModule>
<TestCase name="TestCase3" UID="bde575e2-74dd-4b5b-9d92-c12cc7e6777d" State="Checked" DataSourceId="" />
</TestCase>
<TestCase name="TestCase2" UID="06a4df3b-f072-4f70-a5c3-f0f2ea95654c" State="Checked" DataSourceId="" />
<TestModule name="ds" State="Checked" UID="16b175a7-b286-484d-ba9a-2a5c9f8dd0fc" />
<TestModule name="hh" State="Checked" UID="581f5d85-a777-483b-9b5d-ae2830302878" />
</TestSuite>
XmlNode rootNode = xDoc.SelectSingleNode("/TestSuite");
string s = "16b175a7-b286-484d-ba9a-2a5c9f8dd0fc";
XmlNode l_objXmlNode = null;
foreach (XmlNode node in rootNode.ChildNodes)
{
l_objXmlNode = ProcesNode(node, s);
if (l_objXmlNode != null)
break;
}
private static XmlNode ProcesNode(XmlNode node, string l_selectedNodeUID)
{
XmlNode l_objXmlNode = null;
if (!node.HasChildNodes
|| ((node.ChildNodes.Count == 1) && (node.FirstChild is System.Xml.XmlText)))
{
if (node.Attributes["UID"] != null && node.Attributes["UID"].Value == l_selectedNodeUID)
{
l_objXmlNode = node;
return l_objXmlNode;
}
}
else
{
foreach (XmlNode child in node.ChildNodes)
{
if (child.Attributes["UID"] != null && child.Attributes["UID"].Value == l_selectedNodeUID)
{
l_objXmlNode = child;
break;
}
else
{
return ProcesNode(child, l_selectedNodeUID);
}
}
}
return l_objXmlNode;
}'
I have to find deepest child node from xml file having UID="value" for that i have written above recursive code but l_objXmlNode always giving me null value.I have to find deepest child node from xml file having UID="value" for that i have written above recursive code but l_objXmlNode always giving me null value.
You can use XPath expression to find element with UID attribute equals certain value, anywhere in the XML document :
....
string s = "16b175a7-b286-484d-ba9a-2a5c9f8dd0fc";
XmlNode l_objXmlNode = xDoc.SelectSingleNode(String.Format("//*[#UID='{0}']", s));
Or using LINQ-to-XML :
XDocument doc = XDocument.Load("path to your XML file");
string s = "16b175a7-b286-484d-ba9a-2a5c9f8dd0fc";
XElement l_objXmlNode = doc.Descendants().FirstOrDefault(o => (string)o.Attribute("UID") == s);
Try this...
public static void SearchNodes()
{
XDocument doc = XDocument.Load(#"D:\\Test\\Test2.xml");
var v = from nodes in doc.Descendants("TestCase")
where nodes.Attribute("UID").Value == "06a4df3b-f072-4f70-a5c3-f0f2ea95654c"
select nodes;
foreach (var item in v)
{
Console.Write(item);
}
}
You will get following output
<TestCase name="TestCase2" UID="06a4df3b-f072-4f70-a5c3-f0f2ea95654c" State="Che
cked" DataSourceId="" />
You can pass the expected value as parameter to SearchNodes function.
So, I have a problem to modify my XML-document. Here is my XML
<CookBook>
<Recipe id="1">
<Title>Best recipe</Title>
<Category>...</Category>
<Description>Some text</Description>
<Amount>10</Amount>
<Ingredient>
<li>Ingredient 1</li>
<li>Ingredient 2</li>
</Ingredient>
<RecipeText>
<li>Step 1</li>
<li>Step 2</li>
<li>Step 3</li>
</RecipeText>
</Recipe>
<Recipe id="2">
<Title>Best recipe2</Title>
<Category>...</Category>
<Description>Some text</Description>
<Amount>10</Amount>
<Ingredient>
<li>Ingredient 1</li>
<li>Ingredient 2</li>
<li>Ingredient 3</li>
</Ingredient>
<RecipeText>
<li>heat the oven</li>
<li>Do something</li>
<li>Do something</li>
</RecipeText>
</Recipe>
</CookBook>
So I need to update specific recipe’s li elements which are inside of Ingredient element. But I really don't know how... I have an ingredients list, which contains values that I want to my XML.
foreach (var item in lvAddIngredient.Items)
{
string text = item.ToString();
ingredients.Add(text);
}
When I create a new Recipe I use this code
var doc = XDocument.Load("recipeXML.xml");
var newElement = new XElement("Recipe", new XAttribute("id", id.ToString()),
new XElement("Title", txtTitle.Text),
new XElement("Category", selectedCategory.ToString()),
new XElement("Description", txtDescription.Text),
new XElement("Amount", txtAmount.Text),
new XElement("Ingredient", ingredients.Select(text => new XElement("li", text))),
new XElement("RecipeText", recipeText.Select(text => new XElement("li", text))));
doc.Element("CookBook").Add(newElement);
doc.Save("recipeXML.xml");
But I don't know how to update these li elements value. I have tried something like this, but the syntax is wrong.
var xdoc = XDocument.Load("recipeXML.xml");
string id = lbRecipes.SelectedValue.ToString();
var items = from item in xdoc.Descendants("Recipe")
where item.Attribute("id").Value == id
select item;
foreach (XElement ele in items)
{
ele.SetElementValue("Title", txtTitle.Text);
ele.SetElementValue("Category",cbAddCategory.Text);
ele.SetElementValue("Amount", txtAmount.Text);
ele.SetElementValue("Description", txtDescription.Text);
ele.SetElementValue("Ingredient", ingredients.Select(text => ele.SetElementValue("li", text)));
}
Just use your row identifier "li" to get what you need with your loop.
I suggest you to create a tree view for the XML, with the help of the tree view you can browse through the elements existing in the XML, select any value that you would like to update, serialize the tree view after updating the value and save it back to the XML file.
You can create treeview with the help of this snippet!
try
{
treeView1.Nodes.Clear();
treeView1.Nodes.Add(new TreeNode(doc.DocumentElement.Name));
TreeNode tNode = new TreeNode();
tNode = treeView1.Nodes[0];
AddNode(doc.DocumentElement, tNode);
treeView1.Show();
}
catch (XmlException xmlEx)
{
MessageBox.Show(xmlEx.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void AddNode(XmlNode inXmlNode, TreeNode inTreeNode)
{
XmlNode xNode;
TreeNode tNode;
XmlNodeList nodeList;
int i;
if (inXmlNode.HasChildNodes)
{
nodeList = inXmlNode.ChildNodes;
for (i = 0; i <= nodeList.Count - 1; i++)
{
xNode = inXmlNode.ChildNodes[i];
inTreeNode.Nodes.Add(new TreeNode(xNode.Name));
tNode = inTreeNode.Nodes[i];
AddNode(xNode, tNode);
}
}
else
{
inTreeNode.Text = (inXmlNode.InnerText).Trim();
}
I have an XML File, generated by library written in c++:
<?xml version="1.0" encoding="UTF-8" ?>
<main>
<days>
<day>
<date>27.06.2014</date>
<p/>
</day>
<day>
<date>28.06.2014</date>
<p>
<short>short value</short>
<name>name value</name>
<type>type value</type>
<aud>aud value</aud>
<tr>tr value</tr>
<added>added value</added>
</p>
<p>
<short>short value</short>
<name>name value</name>
<type>type value</type>
<aud>aud value</aud>
<tr>tr value</tr>
<added>added value</added>
</p>
</day>
...
</days>
<di>
<did>
<dayname>Пн</dayname>
<sw>1</sw>
<st>8:00-9:35</st>
</did>
<did>
<dayname>Вт</dayname>
<sw>2</sw>
<st>9:45-11:20</st>
</did>
...
</di>
</main>
I read these xml file like below:
XmlTextReader r = new XmlTextReader("out.xml");
while (r.Read())
{
if (r.Name == "date") { r.Read(); dates[c1] = (r.Value); c1++; }
else if (r.Name == "short") { r.Read(); shorts[c2] = (r.Value); c2++; }
else if (r.Name == "name") { r.Read(); names[c3] = (r.Value); c3++; }
else if (r.Name == "type") { r.Read(); types[c4] = (r.Value); c4++; }
else if (r.Name == "aud") { r.Read(); auds[c5] = (r.Value); c5++; }
else if (r.Name == "tr") { r.Read(); trs[c6] = (r.Value); c6++; }
else if (r.Name == "sw") { r.Read(); ws[c7] = (r.Value); c7++; }
else if (r.Name == "st") { r.Read(); st[c8] = (r.Value); c8++; }
}
r.Close();
How do I parse the file, so that I can understand what the parameter to which the day belongs, especially if there are several in one day ("p" in this case)? Trying to find a solution in the Internet, many people say it is better to use "LINQ to XML" or "XPath", but how to maintain object dependencies nobody says.
Load your xml using the XDocument class and then you can traverse it using the Descendants or Element methods.
var xml = XDocument.Load("your xml string");
foreach (var day in xml.Descendants("day"))
{
var pChildren = day.Descendants("p").ToList();
var aretThereMorePs = pChildren.Count() > 1;
foreach (var p in pChildren)
{
var shortVal = (string)p.Element("short");
//etc
}
}
I'm trying to figure out the simplest way to take xml like this:
<Car>
<Description Model="Ford ">Blue </Description>
</Car>
into this:
<Car>
<Description Model="Ford">Blue</Description>
</Car>
Using LINQ to XML, how about something like:
foreach (var element in doc.Descendants())
{
foreach (var attribute in element.Attributes())
{
attribute.Value = attribute.Value.Trim();
}
foreach (var textNode in element.Nodes().OfType<XText>())
{
textNode.Value = textNode.Value.Trim();
}
}
I think that should work... I don't believe you need to use ToList to avoid disturbing things as you iterate, as you're not changing the structure of the XML document, just the text.
Try this. Don't forget to recurse through your ChildNodes ...
protected void Page_Load(object sender, EventArgs e)
{
XmlDocument doc = new XmlDocument();
doc.Load(#"c:\temp\cars.xml");
Recurse(doc.ChildNodes);
}
private void Recurse(XmlNodeList nodes)
{
foreach (XmlNode node in nodes)
{
if (node.InnerText != null)
node.InnerText = node.InnerText.Trim();
if (node.Attributes != null)
{
foreach (XmlAttribute att in node.Attributes)
att.Value = att.Value.Trim();
}
Recurse(node.ChildNodes);
}
}
If you're not using or can't use LINQ to XML then the below worked well for me with XmlDocument
TrimXmlText(xmlDocument.ChildNodes);
private void TrimXmlText(XmlNodeList xmlNodeList)
{
foreach (XmlNode xmlNode in xmlNodeList)
{
if (xmlNode.NodeType == XmlNodeType.Text)
{
xmlNode.InnerText = xmlNode.InnerText?.Trim();
}
else
{
TrimXmlText(xmlNode.ChildNodes);
}
}
}
My aim is to read this xml file stream:
<?xml version="1.0" encoding="utf-16"?>
<events>
<header>
<seq>0</seq>
</header>
<body>
<orderBookStatus>
<id>100093</id>
<status>Opened</status>
</orderBookStatus>
<orderBook>
<instrumentId>100093</instrumentId>
<bids>
<pricePoint>
<price>1357.1</price>
<quantity>20</quantity>
</pricePoint>
<pricePoint>
<price>1357.0</price>
<quantity>20</quantity>
</pricePoint>
<pricePoint>
<price>1356.9</price>
<quantity>71</quantity>
</pricePoint>
<pricePoint>
<price>1356.8</price>
<quantity>20</quantity>
</pricePoint>
</bids>
<offers>
<pricePoint>
<price>1357.7</price>
<quantity>51</quantity>
</pricePoint>
<pricePoint>
<price>1357.9</price>
<quantity>20</quantity>
</pricePoint>
<pricePoint>
<price>1358.0</price>
<quantity>20</quantity>
</pricePoint>
<pricePoint>
<price>1358.1</price>
<quantity>20</quantity>
</pricePoint>
<pricePoint>
<price>1358.2</price>
<quantity>20</quantity>
</pricePoint>
</offers>
<lastMarketClosePrice>
<price>1356.8</price>
<timestamp>2011-05-03T20:00:00</timestamp>
</lastMarketClosePrice>
<dailyHighestTradedPrice />
<dailyLowestTradedPrice />
<valuationBidPrice>1357.1</valuationBidPrice>
<valuationAskPrice>1357.7</valuationAskPrice>
<lastTradedPrice>1328.1</lastTradedPrice>
<exchangeTimestamp>1304501070802</exchangeTimestamp>
</orderBook>
</body>
</events>
I created (based on the post here: http://blogs.msdn.com/b/xmlteam/archive/2007/03/24/streaming-with-linq-to-xml-part-2.aspx
a function
public IEnumerable<XElement> readElements(XmlReader r, string matchName)
{
//r.MoveToContent();
while (r.Read())
{
switch (r.NodeType)
{
case XmlNodeType.Element:
{
if (r.Name == matchName)
{
XElement el = XElement.ReadFrom(r) as XElement;
if (el != null)
yield return el;
} break;
}
}
}
}
which I planned to use in the following way
IEnumerable<XElement> xBids = readElements(xmlReader, "bids");
publishPricePoint(xBids, "bids");
IEnumerable<XElement> xOffers = readElements(xmlReader, "offers");
publishPricePoint(xOffers, "offers");
where the method publishPricePoint looks like this:
public void publishPricePoint(IEnumerable<XElement> ie, string side)
{
PricePoint p = new PricePoint();
var ci = CultureInfo.InvariantCulture.Clone() as CultureInfo;
ci.NumberFormat.NumberDecimalSeparator = ".";
var bids = (from b in ie.Elements() select b).ToList();
foreach (XElement e in bids)
{
p.price = decimal.Parse(e.Element("price").Value, ci);
p.qty = int.Parse(e.Element("quantity").Value, ci);
OnPricePointReceived(this, new MessageEventArgs(p, side));
}
}
The problem is, that in this piece of code:
IEnumerable<XElement> xBids = readElements(xmlReader, "bids");
publishPricePoint(xBids, "bids");
IEnumerable<XElement> xOffers = readElements(xmlReader, "offers");
publishPricePoint(xOffers, "offers");
only first two lines work, ie. only bids can be read, not the offers. What is wrong with this? For me, it looks like, there XmlReader disappears after bids have been read.
Thank you for help
================== Other solution =================
while (xmlReader.Read())
{
#region reading bids
if (xmlReader.IsStartElement("bids"))
{
readingBids = true;
readingOffers = false;
}
if (xmlReader.NodeType == XmlNodeType.EndElement && xmlReader.Name == "bids")
{
readingBids = false;
readingOffers = false;
}
if (readingBids == true)
{
if (xmlReader.IsStartElement("price"))
price = xmlReader.ReadElementContentAsDecimal();
if (xmlReader.IsStartElement("quantity"))
{
qty = xmlReader.ReadElementContentAsInt();
OnPricePointReceived(this, new MessageEventArgs(price, qty, "bid"));
}
}
#endregion
#region reading offers
if (xmlReader.IsStartElement("offers"))
{
readingBids = false;
readingOffers = true;
}
if (xmlReader.NodeType == XmlNodeType.EndElement && xmlReader.Name == "offers")
{
readingBids = false;
readingOffers = false;
}
if (readingOffers == true)
{
if (xmlReader.IsStartElement("price"))
price = xmlReader.ReadElementContentAsDecimal();
if (xmlReader.IsStartElement("quantity"))
{
qty = xmlReader.ReadElementContentAsInt();
OnPricePointReceived(this, new MessageEventArgs(price, qty, "offer"));
}
}
}
I think you will have to close and reopen the XmlReader. It simply is in EOF state.
Your solution requires reading everything twice, not too efficient.
Unless your XML is very large (eg > 100 MB) it would be much faster to read it all into an XDocument and filter the bids and offers out with Linq.
Edit: OK, so your data is continuously streamed. That means you can't use a single-tag filter, you'd be skipping the others.
A basic idea: Read every element, with XElement.ReadFrom()
push the elements you want into (separate) queues.
you'll want asynchronous processing. Use the TPL or the (beta) async/await features.
Why dont you do something like this
XDocument document = XDocument.Load(#"XMLFile1.xml");
var bidResults = (from br in document.Descendants("bids")
select br).ToList();
var offerResults = (from or in document.Descendants("offers")
select or).ToList();
then you can just iterate with a foreach (Xelement element in bidResults) to get all the data of the bids and also the data from the offers
foreach (XElement xElement in returnResult)
{
Offer off = new Offer();
off.price = xElement.Element("price") != null ? xElement.Element("price").Value : "";
off.quantity = xElement.Element("quantity") != null ? xElement.Element("quantity").Value : "";
}