Get label of svg element according to its id - c#

I want to get label of svg element. I wrote a console application and thougt svg file as xml. I am trying to get labels according to id of element. When i wrote code below, i got all ids but i cant get label with that row. How can i access the label? An example of element is;
<rect
style="fill:#cccccc"
id="21"
width="35.823246"
height="35.823246"
x="299.87155"
y="65.999405"
class="seatObj"
inkscape:label="A22" />
And codes are;
class Program
{
static void Main(string[] args)
{
XmlDocument doc = new XmlDocument();
doc.Load(#"seatChart-01.svg");
XmlNodeList elementList = doc.GetElementsByTagName("rect");
string[] labels = new string[elementList.Count];
for (int i = 0; i < elementList.Count; i++)
{
int id = int.Parse(elementList[i].Attributes["id"].Value);
labels[id] = elementList[i].Attributes["inkspace:label"].Value;
}
for (int i = 0; i < labels.Length; i++)
{
Console.WriteLine(labels[i]);
}
Console.ReadLine();
}
}

elementList[i].Attributes["inkspace:label"].Value
should be
elementList[i].Attributes["label", "http://www.inkscape.org/namespaces/inkscape"].Value
I'm assuming that the namespace is that of the inkscape drawing program here. To confirm that look for something on the root element that looks like this...
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"

Related

Xml searching recursively for a specific value

In my C# app I am reading an xml document, and in it, are tags containing paths to where .png and .jpg files are being kept. These tags are , and .
I could simply create an XmlNodeList object for each of these tags, such as
XmlNodeList image = _doc.GetElementsByTagName.("Image");
XmlNodeList background = _doc.GetElementsByTagName.("BackgroundImage");
XmlNodeList foreground = _doc.GetElementsByTagName.("ForegroundImage");
for(int i = 0; i < image.count; i++)
{
//..code
}
for(int i = 0; i < background .count; i++)
{
//..code
}
for(int i = 0; i < foreground .count; i++)
{
//..code
}
Clunky, I know. But, is there a way where I can have the application recursively find the tags that contains the word "Image" and return it as a single XmlNodeList? Can it be done? Would this be the best approach? Many thanks in advance.

c# HtmlAgilityPack for on nodes array

I'm using html agility pack and after I got array of nodes:
HtmlNode[] nodes = document.DocumentNode.SelectNodes("//tbody[#class='table']").ToArray();
now i want to run a for loop one each nodes[i]. I've tried this:
for (int i = 0; i < 1; i++)
{
if (t == null)
t = new Model.Track();
HtmlNode[] itemText = nodes[i].SelectNodes("//td[#class='artist']").ToArray();
for (int x = 0; x < itemText.Length; x++)
{ //doing something }
the problem is that the itemtext array isn't focusing on nodes[i] .
but brings out an array of all the ("//td[#class='artist']") in the html document.
help?
Using //td[#class='artist'] will fetch all columns with artist class from your document.DocumentNode.
Using .//td[#class='artist'] (Notice the dot at the begining) will fetch all columns with artist class from the current selected node, which in your case is nodes[i].

The requested member of the collection does not exist, MS Word

I tried to run a sample program from dotnetpearls.com and at first the program didn't work at all.
Apparently I had to run VS Express 2012 as Administrator, before I could start an Application object. After that, the next time it errors out, is when I try to print out the text from the document. Error happens at string text = doc.Words[i].Text;
using System;
using Microsoft.Office.Interop.Word;
namespace WordTestProgram
{
class Program
{
static void Main(string[] args)
{
Application app = new Application();
Document doc = app.Documents.Open("C:\\word.doc");
int count = doc.Words.Count;
for (int i = 0; i <= count; i++)
{
string text = doc.Words[i].Text;
Console.WriteLine("Word {0} = {1}",i,text);
}
app.Quit();
}
}
}
I know for a fact that the document I am trying to extract data from, does have 3 words and 3 spaces in it. So it's not empty.
I found the answer myself
Instead of: int i = 0; i <= count; i++
I should do: int i = 1; i <= count; i++
Apparently member 0 in the array is null and the program can't handle that.

Converting XML to String[] help

I'm having Trouble converting the contents of XML document to an int[] or string[]
I'm saving the x and y coordinates of 20 different picture boxes on the screen (For a jigsaw Puzzle Program) to an xml file, and are now trying to load the saved coordinates and update the jigsaw puzzle pieces to those saved locations.
Heres my code:
XmlWriter XmlWriter1;
XmlReader XmlReader1;
private void Form1_Load(object sender, EventArgs e)
{
//-------------------------------------------------
//Load Events
//-------------------------------------------------
SavedPositions = new int[40];
}
//-------------------------------------------------------
//Saves The Current Tile Locations To A Hidden XML File
//-------------------------------------------------------
public void SavePicPositionsXML()
{
using (XmlWriter1 = XmlWriter.Create("SavedPuzzle.xml"))
{
XmlWriter1.WriteStartDocument();
XmlWriter1.WriteStartElement("MTiles");
for (int i = 0; i < JigsawImgCount; i++)
{
XmlWriter1.WriteStartElement("Tile");
XmlWriter1.WriteElementString("X",Convert.ToString(MTiles[i].Pic.Location.X));
XmlWriter1.WriteElementString("Y",Convert.ToString(MTiles[i].Pic.Location.Y));
XmlWriter1.WriteEndElement();
}
XmlWriter1.WriteEndElement();
XmlWriter1.WriteEndDocument();
}
}
//---------------------------------------------------------------
//Reads Text From A Hidden Xml File & Adds It To A String Array
//---------------------------------------------------------------
private int ReadXmlFile(int Z)
{
XmlReader1 = XmlReader.Create("SavedPuzzle.xml");
XmlReader1.MoveToContent();
while (XmlReader1.Read())
{
}
// SavedPositions[B] = Convert.ToInt32(XmlReader1.Value.ToString());
return SavedPositions[Z];
}
//-------------------------------------------------
//Loads Saved Tile Positions From A Hidden Xml File
//-------------------------------------------------
private void LoadPositionsXML()
{
G = 0;
for (int i = 0; i < JigsawImgCount; i++)
{
LineX = ReadXmlFile(G);
LineY = ReadXmlFile(G + 1);
MTiles[i].Pic.Location = new Point(LineX, LineY);
G = G + 2;
}
}
What am i doing wrong???
Your ReadXmlFile method isn't doing anything really.
Consider using XmlDocument or XDocument instead of XmlWriter and XmlReader. They are a lot easier to handle.
try this:
XmlDocument document = new XmlDocument();
document.Load(#"D:/SavedPuzzle.xml");
XmlNode topNode = document.GetElementsByTagName("MTiles")[0];
foreach (XmlNode node in topNode.ChildNodes)
{
int X = Int32.Parse(node.ChildNodes[0].InnerText);
int Y = Int32.Parse(node.ChildNodes[1].InnerText);
}
The following LinqToXML statement will extract all tiles into a list in the order they are stored in the document.
I'm assuming an XML file that looks like this:
<xml>
<MTiles>
<Tile>
<X>1</X>
<Y>10</Y>
</Tile>
<Tile>
<X>2</X>
<Y>20</Y>
</Tile>
<Tile>
<X>3</X>
<Y>30</Y>
</Tile>
<Tile>
<X>4</X>
<Y>40</Y>
</Tile>
</MTiles>
</xml>
And this code will load it, and extract all the tiles into an enumerable list. Remember to put a using System.Xml.Linq at the top of the file and build against a recent enough framework (IIRC, it was introduced in .NET 3.5)
XDocument doc = XDocument.Load(/* path to the file, or use an existing reader */);
var tiles = from tile in doc.Descendants("Tile")
select new
{
X = (int)tile.Element("X"),
Y = (int)tile.Element("Y"),
};
foreach (var tile in tiles)
{
Console.WriteLine("Tile: x={0}, y={1}", tile.X, tile.Y);
}
The output from the code above using the XML file I specified is:
Tile: x=1, y=10
Tile: x=2, y=20
Tile: x=3, y=30
Tile: x=4, y=40
EDIT:
If you just want all the X-values as an array of integers, the following LINQ query would work:
int[] allXValues = (from tile in doc.Descendants("Tile")
select (int)tile.Element("X")).ToArray();

Why do I need to count the number of XmlNodes before iterating through and deleting some of them?

I believe I have found a weird bug as follow:
I want to delete the first two nodes in an XmlNodeList.
I know that there may be other ways of doing this (there surely are) but it is the reason why one of the code segments works and one doesn't (the difference being the Count line) that I am interested in.
var strXml = #"<food><fruit type=""apple""/><fruit type=""pear""/><fruit type=""banana""/></food>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(strXml);
XmlNodeList nlFruit = doc.SelectNodes("food/fruit");
for(int i = 0; i < 2; i++)
{
// This produces a null reference exception:
nlFruit[i].ParentNode.RemoveChild(nlFruit[i]);
}
However, if I count the number of nodes in the XmlNodeList it works and I am left with the desired outcome:
var strXml = #"<food><fruit type=""apple""/><fruit type=""pear""/><fruit type=""banana""/></food>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(strXml);
XmlNodeList nlFruit = doc.SelectNodes("food/fruit");
// Count the nodes..
Debug.WriteLine(nlFruit.Count);
for(int i = 0; i < 2; i++)
{
nlFruit[i].ParentNode.RemoveChild(nlFruit[i]);
}
// doc is now: <food><fruit type="banana" /></food>
Both are wrong you should delete from the end
for(int i = 1; i >= 0; i--)
{
nlFruit[i].ParentNode.RemoveChild(nlFruit[i]);
}
because you remove the 0 th element, and 1 st element becomes the 0 th, than you removes 1st element which is null.
May be this will help:
Halloween Problem : http://blogs.msdn.com/mikechampion/archive/2006/07/20/672208.aspx

Categories

Resources