首页 > 解决方案 > How to use a relative path in XDocument.Load with Xamarin?

问题描述

I always get the system not found exception. How can I find a xml file in a bundle of my xamarin.android application?

public Dictionary<string, string> TilePropertiesForTileID(short tileGid)
    {
        Dictionary<string, string> propertiesDict = null;

        try
        {

            // Loading from a file, you can also load from a stream
            var xml = XDocument.Load(Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData), "Assets/Content/tileMap/wood_tileset.tsx"));

            // Query the data and write out a subset of contacts
            var propertiesQuery = from c in xml.Root.Descendants("tile")
                                  where (int)c.Attribute("id") == tileGid
                                  select c.Element("property").Value;


            foreach (string property in propertiesQuery)
            {
                Console.WriteLine("Property: {0}", property);
            }

        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw e;
        }

        return propertiesDict;
    }

This line:

var xml = XDocument.Load(Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData), "Assets/Content/tileMap/wood_tileset.tsx"));

always throws the exception. I don't know How to get access to this file.

updated: Thanks to apineda I am now able to find the file : here is the xml file

<?xml version="1.0" encoding="UTF-8"?>
<tileset version="1.2" tiledversion="1.2.1" name="wood_tileset" 
    tilewidth="32" tileheight="32" tilecount="256" columns="16">
 <image source="wood_tileset.png" width="512" height="512"/>
 <tile id="68">
  <properties>
   <property name="IsTreasure" value="true"/>
  </properties>
 </tile>
</tileset>

标签: xamarinxamarin.android

解决方案


为此,您不一定需要文件的完整路径。由于您将文件放在 Assets 目录中,并且我希望也将其标记为Build ActionAndroidAsset中,因此您只需要使用.AssetManager

如果您在一个活动中,您可以在资产中打开一个文件,如下所示:

Assets.Open("fileName.ext")

如果您在 Assets 目录中添加了子目录,则需要包含完整路径(不包括“Assets”一词)。

使用您的代码作为示例,它应该如下所示:

using (var sReader = new StreamReader(Assets.Open("Content/titleMap/wood_tileset.tsx")))
{
    var xmlDoc = XDocument.Load(sReader);

    // Query the data and write out a subset of contacts
    var propertiesQuery = xmlDoc.Root.Descendants("tile")
                                .Where(item => (int)item.Attribute("id") == tileGid)
                                .SelectMany(a => a.Descendants("property"))
                                .Select(property => new
                                { 
                                    Name = property.Attribute("name").Value, 
                                    Value = property.Attribute("value").Value
                                })
                                .ToList();

    foreach (var property in propertiesQuery)
    {
        Console.WriteLine($"Property Name: {property.Name}, Value: {property.Value}");
    }
}

如您所见,Assets.Open方法的返回被传递到 StreamReader。这using不是必需的,但这将防止打开资源。

然后将 StreamReader 传递给 the 的Load()方法,XDocument其余部分与您拥有的完全相同。

注意:这假设您具有如下文件结构:

Assets    
     Content
       titleMap
          wood_titleset.tsx

希望这可以帮助。-


推荐阅读