0

I have an XmlTextReader to read series of XML files to load some information in to my program.

However, in some XML files I have the file name of an image and I want to load that image.

But the problem is the XML file does not have the full path of the image.

<Image id="ImageId" File="Image.bmp" /> 
<!-- full path is not available. Image is behind XML-->

This means the Image exist where the xml file exists.

for some reason, the only way to get the path of the XML file is to get the path of the XmlTextReader reading the current XML file.

I did some research and I found out you can retrieve the XML path from the XmlTextReader as below:

string path = reader.BaseURI; // this will get the path of reading XML
                              // reader is XmlTextReader

How can I combine path with the image's path?

I have tried the following way:

string FullImagePath = Path.Combine(reader.BaseURI, imagePath);

These are the values of the variables:

  • reader.BaseURI is "file:///D:/.../currentXml.xml"
  • imagePath is "Image.bmp".
  • Finally, FullImagePath, after assigning the result of Path.Combine is file:///D:/.../currentXml.xml\\Image.bmp, which is not what I expect.

Expected path of the image is: D:/.../Image.bmp, in the same directory as currentXml.xml.

So how can I get the path of the image file?

ataravati
  • 8,891
  • 9
  • 57
  • 89
M.kazem Akhgary
  • 18,645
  • 8
  • 57
  • 118

3 Answers3

1
 Path.Combine(Path.DirectoryName(reader.BaseUri), imagePath)
Matthew Whited
  • 22,160
  • 4
  • 52
  • 69
  • As a note, if you want to get rid of the 'file://' scheme from the URI look at the Uri class and the AbsolutePath property. – Matthew Whited Jun 21 '15 at 15:44
  • i fixed it using `Path.Combine(Path.GetDirectoryName(reader.BaseURI), imagePath).Substring(6)` since `file://` is same length always. thanks – M.kazem Akhgary Jun 21 '15 at 15:47
  • 3
    I'd highly recommend using framework methods for removing the scheme. The .substring(6) isn't obvious and could break. (at the least remove the scheme from the BaseUri as this could create invalid paths if a root or absolute path was ever provided in imagePath. – Matthew Whited Jun 21 '15 at 15:56
1

You have a two different problems that you need to solve separately.

Depending on the API used to consume the image file, a file:// URI path may or may not be supported. So you'd want to make that a local path as explained in Convert file path to a file URI?:

string xmlPath = "file://C:/Temp/Foo.xml";
var xmlUri = new Uri(xmlPath); // Throws if the path is not in a valid format.
string xmlLocalPath = xmlUri.LocalPath; // C:\Temp\Foo.xml

Then you want to build the path to the image file, which resides in the same directory as the XML file.

One way to do that is to get the directory that file is in, see Getting the folder name from a path:

string xmlDirectory = Path.GetDirectoryName(xmlLocalPath); // C:\Temp

Then you can add your image's filename:

string imagePath = Path.Combine(xmlDirectory, "image.png"); // C:\Temp\image.png

Or, in "one" line:

string imagePath = Path.Combine(Path.GetDirectoryName(new Uri(reader.BaseURI).LocalPath), 
                                ImagePath);
Community
  • 1
  • 1
CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • thanks for explanation. `GetDirectoryName` did the job. but for getting rid of `file://` i used `Substring(6)`. not pretty but simple, – M.kazem Akhgary Jun 21 '15 at 15:51
  • 3
    That code isn't only "not pretty", it _will_ also break some day. – CodeCaster Jun 21 '15 at 15:52
  • thanks. accepted. one line solution. `new Uri(Path.Combine(Path.GetDirectoryName(reader.BaseURI), ImagePath)).LocalPath` . now it wont break some day! – M.kazem Akhgary Jun 21 '15 at 16:00
  • @M.kazemAkhgary MSDN [mentions that `Path.GetDirectoryName()` _"does not support paths using "file:"_](https://msdn.microsoft.com/en-us/library/system.io.path.getdirectoryname(v=vs.110).aspx), so I doubt that'll work. Edit: it seems to work... – CodeCaster Jun 21 '15 at 16:01
  • 1
    It does seem to work, but it's not supported, so may change working in any .NET version. The proper "oneliner" you seem to favor is `string imagePath = Path.Combine(Path.GetDirectoryName(new Uri(reader.BaseURI).LocalPath), ImagePath);`. – CodeCaster Jun 21 '15 at 16:05
0

As you are dealing with resolving URLs I would suggest to use XmlUrlResolver in System.Xml:

string localPath = new XmlUrlResolver().ResolveUri(new Uri(baseUri), imageName).LocalPath;
Martin Honnen
  • 160,499
  • 6
  • 90
  • 110