开发者

C# XML properties

开发者 https://www.devze.com 2023-02-04 05:23 出处:网络
I was wondering if someone could help me out with an xml problem I\'m having. I\'m trying to parse this xml file:

I was wondering if someone could help me out with an xml problem I'm having. I'm trying to parse this xml file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE map SYSTEM "http://mapeditor.org/dtd/1.0/map.dtd">
<map version="1.0" orientation="orthogonal" width="32" height="38" tilewidth="32" tileheight="32">
 <properties>
  <property name="Event" value="var MakeMapEvent = function(layer, mapPosition) {  System.Console.Out.WriteLine(layer); }"/>
  <property name="Starting Position" value="9,6"/>
 </properties>
 <tileset name="Void Tileset 2x - 4" firstgid="1" tilewidth="32" tileheight="32">
  <image source="Void Tileset 2x - 4.png"/>
 </tileset>
 <tileset name="Untitled" firstgid="121" tilewidth="32" tileheight="32" spacing="32">
  <image source="Collisions.png"/>
  <tile id="0">
   <properties>
    <property name="Collision Layer" value="True"/>
   </properties>
  </tile>
 </tileset>
 <layer name="Tile Layer 2" width="32" height="38">
  <data encoding="base64" compression="gzip">
   H4sIAAAAAAAAAO3OMQqAMBBE0ai1Wqs3inVOoAfI/SvHQrCwMLBhFf6DafdvCMB3NVqrdU79Xhu00ak/abO2OPUB4MlufG8tbGfjfiz44WxvFfrXD2/+sO6n2w/R+PbffkhObQAAUN8BA9MHSAATAAA=
  </data>
 </layer>
 <layer name="Tile Layer 1" width="32" height="38">
  <data encoding="base64" compression="gzip">
   H4sIAAAAAAAAAO1XPXPCMAzVT2Bj6VrajSvtCmVOuvKxQpOxBf7/UuvQu+hcS7Yp2fru3vmonbxnRbJVon/cA4+Bs8Cnyrl74SVwEfhaOecBvkHP/1I03ivnPO1FgpaHNnAqY4zGmbOAmMW0YrgRjV3lnAXELKYVQ8TLis+0QpvRiYdD4CTwS7R7Y30ux2r1z+KBn3uQkbUvxnr2uiI7PjX6HMujeJiL/ly0PykdY86thuwcK9XHd/wWD53o96J9ovR33oh+KsdyuRGvA9kDx+CZrns/kV+LW+Ode1n/kfGQqjmOwRtd9x7P8ftmGe6prH4tfY7BOrF3JtfEKsNDhT4lNDxyrnN+9M6IupiQXx9EQ72XajM4Py7O2NGQw/DkocSDjiHnx6eMbeL3mYYchqccEDPLh85jrrudMx5pyGF4KoUXi1wtARvhWnkq7UPYq3UP3lrPNX2IPjvAVYWHZWJ9rgY8bX6upd/fxfKAfNd3Y0kNxNq4e3HHNIUecB9pfe+O8rQbRfjIeUC+aX38rVa7lee28o6UB6yPUdL/QpscbY3Yw0StT73X8gboMyenHXvQPYL+trG29907tRes9bS1B90jYH1K28t79C+oj75AG9A9gqddspdczGOwlu4R0HPUamsPNf8npM7YW7VvAfJWU2vnzpu/wup7sG99XowBfR7qMXVejAGr70gB/nL3z1hgb/w9xszHWvwAqq1WOgATAAA=
  </data>
 </layer>
 <layer name="Tile Layer 3" width="32" height="38">
  <data encoding="base64" compression="gzip">
   H4sIAAAAAAAAAGNgGAXUAiw4xBmBmAmImenoFmTAC8R8QMw/QPZLArEUEEuToXc07IgLu9FwIj+NjQLagtG0SVzaNKSDW0bBKBgFQw9oIbF1B8B+MyA2B2ILILakkR346gknIHYGYhcgdqWR/fjqCT8g9gfiABrZDQLDsQ1jBMTGA2w/CKsPkP22o24YNG6Ata8GKj2CwsAOiO0HyP5RgAkA54+5BwATAAA=
  </data>
 </layer>
 <layer name="Tile Layer 4" width="32" height="38">
  <data encoding="base64" compression="gzip">
   H4sIAAAAAAAAAO3OMQ5AQABE0UWBAgUKFCgcyiW4f2ck2ykVE/Jf8uuZEAAAAPAXmzpitzMGvJGrQpWm/VZ1qjftz2pRq9pNH4CvSVSqMtN+pWrVmPYHNarJtI+nC1aVlIcAEwAA
  </data>
 </layer>
 <objectgroup name="Object Group 4" width="0" height="0" x="-1"/>
 <layer name="Collision Layer 1" width="32" height="38" x="-1">
  <properties>
   <property name="Collision Layer" value="True"/>
   <property name="Test" value="True"/>
  </properties>
  <data encoding="base64" compression="gzip">
   H4sIAAAAAAAAAN2VSQ7EIAwE+fb8fq4R8lLtJYdYQgqyoRzcmHO+YT9jEN8k35tHvmxPb2zzo3OyfBt8xf/Myau/5XuDfy4fsQqfzFXtUd8k39N7dscn+B4vmpPciP68c810Ff2TsibKK/Mrvcrbq8qvmMLfsEn+9vkTNsnNmit7deIr97+bA+lh2bpODuobQvelsR2+WgdrTZVPNE1y8OrYuQNEG1kP6LJprPXtrZ18x55MqsuqFrP6UlZVi3cMYVNWtb9mbEW7hKvqUu0rGT/zq1rf5k/m0KnlFD8ad9wGvxo7qUPKV+/X1+0Pfn2cLQATAAA=
  </data>
 </layer>
</map>

The problem I'm having is I want to get the properties for the map. I can handle the properties of the layers/tilesets fine using List layernodes = layer.Descendants().ToList(); and List tilesetSubNodes = tileset.Descendants().ToList(); but if i do that for the map as a whole, I get everything within map, which will be wasteful to process. I tried using var properties = from x in localmap.Descendants("properties") select x; but that picks up the other properties sections as well. Is there a way to just get the properties group underneath map and none of the others? If it matters, here's how I'm currently parsing the file

public static TiledMap MakeMapFromXML(string xmlMapFile)
        {
            bool resettileproperties = false;
            bool resetextendedproperties = false;
            List<KeyValuePair<string, string>> extendedProperties = null;
            Dictionary开发者_运维百科<int, KeyValuePair<string, string>> tileproperties = null;
            TiledMap map = null;
            string test;
            Orientation orientation = Orientation.Orthogonal;
            int mapwidth = 0, mapheight = 0, tilewidth = 0, tileheight = 0;
            double version;
            try
            {
                if (File.Exists(xmlMapFile))
                {
                    doc = XDocument.Load(xmlMapFile);
                    string name = Path.GetFileNameWithoutExtension(xmlMapFile);
                    int firstGID = 0;
                    var maps = from x in doc.Descendants("map") select x;
                    string source = "";
                    foreach (var localmap in maps)
                    {
                        var tilesets = from x in localmap.Descendants("tileset") select x;
                        var layers = from x in localmap.Descendants("layer") select x;
                        var objectgroups = from x in localmap.Descendants("objectgroup") select x;
                        var properties = from x in localmap.Descendants("properties") select x;
                        Image tilesetSource = null;
                        List<XAttribute> mainmapatts = localmap.Attributes().ToList();
                        List<XElement> props = localmap.Descendants().ToList();
                        if (mainmapatts != null)
                        {
                            foreach (XAttribute attribute in mainmapatts)
                            {
                                switch (attribute.Name.LocalName)
                                {
                                    case "version":
                                        Double.TryParse(attribute.Value, out version);
                                        break;
                                    case "orientation":
                                        Enum.TryParse<Orientation>(attribute.Value, out orientation);
                                        break;
                                    case "width":
                                        Int32.TryParse(attribute.Value, out mapwidth);
                                        break;
                                    case "height":
                                        Int32.TryParse(attribute.Value, out mapheight);
                                        break;
                                    case "tilewidth":
                                        Int32.TryParse(attribute.Value, out tilewidth);
                                        break;
                                    case "tileheight":
                                        Int32.TryParse(attribute.Value, out tileheight);
                                        break;
                                }
                            }
                        }
                        if (orientation == Orientation.Orthogonal)
                        {
                            map = new TiledMap(name, mapwidth, mapheight, tilewidth, tileheight);
                        }
                        if (orientation == Orientation.Isometric)
                        {
                            //Not implemented yet
                            return null;
                            //map = new IsometricMap();
                        }
                        TileSet activetileset;
                        #region Load TileSets
                        foreach (var tileset in tilesets)
                        {
                            List<XAttribute> tilesetAtts = tileset.Attributes().ToList();
                            if (tilesetAtts != null)
                            {
                                foreach (XAttribute attribute in tilesetAtts)
                                {
                                    switch (attribute.Name.LocalName)
                                    {
                                        case "firstgid":
                                            int.TryParse(attribute.Value, out firstGID);
                                            break;
                                        case "name":
                                            name = attribute.Value;
                                            break;
                                        case "tilewidth":
                                            Int32.TryParse(attribute.Value, out tilewidth);
                                            break;
                                        case "tileheight":
                                            Int32.TryParse(attribute.Value, out tileheight);
                                            break;
                                    }
                                }
                            }
                            XElement subnodeElement = null;
                            string key = "";

                            #region Load Tileset Subnodes
                            List<XElement> tilesetSubNodes = tileset.Descendants().ToList();
                            {
                                foreach (XElement subnode in tilesetSubNodes)
                                {
                                    List<XAttribute> attributes = subnode.Attributes().ToList();
                                    if (attributes != null)
                                    {
                                        switch (subnode.Name.LocalName)
                                        {
                                            case "image":
                                                for (int i = 0; i < attributes.Count; i++)
                                                {
                                                    if (String.Compare(attributes[i].Name.LocalName, "source", true) == 0)
                                                    {
                                                        source = attributes[i].Value;
                                                    }
                                                }
                                                break;
                                            case "tile":
                                                for (int i = 0; i < attributes.Count; i++)
                                                {
                                                    if (String.Compare(attributes[i].Name.LocalName, "id", true) == 0)
                                                    {
                                                        key = attributes[i].Value;
                                                    }
                                                }
                                                //Need to add null check here
                                                List<XElement> propertyNodes = subnode.Descendants().ToList();
                                                if (propertyNodes != null)
                                                {
                                                    foreach (XElement propertyNode in propertyNodes)
                                                    {
                                                        foreach (XElement subPropertyNode in propertyNode.DescendantNodes())
                                                        {
                                                            string keyname = null;
                                                            string keyvalue = null;
                                                            foreach (XAttribute attribute in ((XElement)subPropertyNode).Attributes())
                                                            {
                                                                if (String.Compare(attribute.Name.LocalName, "name") == 0)
                                                                {
                                                                    keyname = attribute.Value;
                                                                }
                                                                else if (String.Compare(attribute.Name.LocalName, "value") == 0)
                                                                {
                                                                    keyvalue = attribute.Value;
                                                                }
                                                            }
                                                            if (keyname != null && keyvalue != null)
                                                            {
                                                                if (tileproperties == null || resettileproperties)
                                                                {
                                                                    tileproperties = new Dictionary<int, KeyValuePair<string, string>>();
                                                                    resettileproperties = false;
                                                                    tileproperties.Add(Int32.Parse(key), new KeyValuePair<string, string>(keyname, keyvalue));
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                                break;
                                        }
                                    }
                                }
                            }
                            #endregion
                            if (File.Exists(source))// && !(name.ToLower().Contains("Collision") || name.ToLower().Contains("collision")))
                            {
                                tilesetSource = LoadTileSet(source);
                                if (tilesetSource != null)
                                {
                                    activetileset = GenerateTileSet(tilesetSource, tilewidth, tileheight, name, firstGID);
                                    if (!resettileproperties)
                                    {
                                        activetileset.AddTilePropertySet(tileproperties);
                                        resettileproperties = true;
                                    }
                                    if (tileset != null && map != null)
                                        map.AddTileSet(activetileset);
                                }
                            }
                        }
                        #endregion
                        #region Load Layers
                        Encoding encoding = Encoding.None;
                        Compression compression = Compression.None;
                        string datastring = "";
                        Layer locallayer;
                        bool CollisionLayer = false;
                        foreach (var layer in layers)
                        {
                            locallayer = null;
                            List<XAttribute> atts = layer.Attributes().ToList();
                            if (atts != null)
                            {
                                foreach (XAttribute attribute in atts)
                                {
                                    switch (attribute.Name.LocalName)
                                    {
                                        case "name":
                                            name = attribute.Value;
                                            break;
                                        case "width":
                                            Int32.TryParse(attribute.Value, out mapwidth);
                                            break;
                                        case "height":
                                            Int32.TryParse(attribute.Value, out mapheight);
                                            break;
                                    }
                                }
                            }
                            List<XElement> layernodes = layer.Descendants().ToList();
                            if (layernodes != null)
                            {
                                foreach (XElement node in layernodes)
                                {
                                    switch (node.Name.LocalName)
                                    {
                                        case "data":
                                            List<XAttribute> layerSubNodeAtts = node.Attributes().ToList();
                                            if (layerSubNodeAtts != null)
                                            {
                                                foreach (XAttribute attribute in layerSubNodeAtts)
                                                {
                                                    switch (attribute.Name.LocalName)
                                                    {
                                                        case "encoding":
                                                            Enum.TryParse<Encoding>(attribute.Value, out encoding);
                                                            break;
                                                        case "compression":
                                                            Enum.TryParse<Compression>(attribute.Value, out compression);
                                                            break;
                                                    }
                                                }
                                            }
                                            datastring = node.Value;
                                            if (encoding == Encoding.Base64 && compression == Compression.Gzip)
                                            {
                                                datastring = Utilities.GunzipAndDecodeData(datastring.Trim());
                                            }
                                            break;
                                        case "properties":
                                            List<XElement> layerSubNodes = node.Descendants().ToList();
                                            if (layerSubNodes != null)
                                            {
                                                foreach (XElement subnodes in node.DescendantNodes())
                                                {
                                                    string keyname = "";
                                                    string keyval = "";
                                                    foreach (XAttribute attribute in subnodes.Attributes())
                                                    {
                                                        bool valid = false;
                                                        if (attribute.NextAttribute != null && String.Compare(attribute.Value, "collision layer", true) == 0 && Boolean.TryParse(attribute.NextAttribute.Value, out valid) && valid)
                                                        {
                                                            CollisionLayer = true;
                                                        }
                                                        else
                                                        {
                                                            if (extendedProperties == null || resetextendedproperties)
                                                            {
                                                                extendedProperties = new List<KeyValuePair<string, string>>();
                                                                resetextendedproperties = false;
                                                            }
                                                            if (attribute.NextAttribute != null)
                                                                extendedProperties.Add(new KeyValuePair<string, string>(attribute.Value, attribute.NextAttribute.Value));
                                                        }
                                                    }
                                                }
                                            }
                                            break;
                                    }
                                }
                            }
                            if (CollisionLayer)
                            {
                                if (!resetextendedproperties)
                                {
                                    locallayer = new CollisionLayer(name, mapwidth, mapheight, tilewidth, tileheight, datastring, extendedProperties);
                                    resetextendedproperties = true;
                                }
                                else
                                {
                                    locallayer = new CollisionLayer(name, mapwidth, mapheight, tilewidth, tileheight, datastring);
                                }
                            }
                            else
                            {
                                if (!resetextendedproperties)
                                {
                                    locallayer = new Layer(name, mapwidth, mapheight, tilewidth, tileheight, datastring, extendedProperties);
                                    resetextendedproperties = true;
                                }
                                else
                                {
                                    locallayer = new Layer(name, mapwidth, mapheight, tilewidth, tileheight, datastring);
                                }
                            }
                            if (locallayer != null)
                                map.AddLayer(locallayer);
                        }
                        #endregion
                        foreach (var objectgroup in objectgroups)
                        {
                            //TODO
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.Out.WriteLine("Error Parsing XML file " + ex.Message);
            }
            return map;
        }


localmap.Element("properties").Elements("property") should work


Descendants includes children, grandchildren, great-grandchildren, etc. I think you want to use Elements("properties").Elements("property").

0

精彩评论

暂无评论...
验证码 换一张
取 消