| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483 |
- // Copyright (c) Craftwork Games. All rights reserved.
- // Licensed under the MIT license.
- // See LICENSE file in the project root for full license information.
- using System;
- using System.Xml;
- using Microsoft.Xna.Framework;
- namespace MonoGame.Extended.Serialization.Xml;
- /// <summary>
- /// Provides extension methods for <see cref="XmlReader"/> to simplify reading and parsing XML Attributes into
- /// strong-typed values.
- /// </summary>
- public static class XmlReaderExtensions
- {
- /// <summary>
- /// Reads an XML attribute as an <see langword="int"/> value.
- /// </summary>
- /// <param name="reader">The XML reader instance.</param>
- /// <param name="attributeName">The name of the attribute to read.</param>
- /// <returns>The <see langword="int"/> value parsed from the value of the specified attribute.</returns>
- /// <exception cref="XmlException">
- /// Thrown when the attribute is missing, or when the attribute value cannot be parsed as an <see langword="int"/>.
- /// </exception>
- public static int GetAttributeInt(this XmlReader reader, string attributeName)
- {
- string value = reader.GetAttribute(attributeName);
- if (value == null)
- {
- throw new XmlException($"Required attribute '{attributeName}' is missing.");
- }
- try
- {
- return int.Parse(value);
- }
- catch (Exception ex) when (ex is FormatException || ex is OverflowException)
- {
- throw new XmlException(
- $"Invalid integer format for attribute '{attributeName}'. Expected integer, but got '{value}'",
- ex
- );
- }
- }
- /// <summary>
- /// Reads an XML attribute as an <see langword="int"/> value, returning a default value if the attribute is missing or invalid.
- /// </summary>
- /// <param name="reader">The XML reader instance.</param>
- /// <param name="attributeName">The name of the attribute to read.</param>
- /// <param name="defaultValue">The default value to return if the attribute is missing or cannot be parsed.</param>
- /// <returns>The <see langword="int"/> value parsed from the value of the specified attribute, or the default value if parsing fails.</returns>
- public static int GetAttributeInt(this XmlReader reader, string attributeName, int defaultValue)
- {
- string value = reader.GetAttribute(attributeName);
- if (value == null)
- {
- return defaultValue;
- }
- try
- {
- return int.Parse(value);
- }
- catch
- {
- return defaultValue;
- }
- }
- /// <summary>
- /// Reads an XML attribute as a <see langword="float"/> value.
- /// </summary>
- /// <param name="reader">The XML reader instance.</param>
- /// <param name="attributeName">The name of the attribute to read.</param>
- /// <returns>The <see langword="float"/> value parsed from the specified attribute.</returns>
- /// <exception cref="XmlException">
- /// Thrown when the attribute is missing, or when the attribute value cannot be parsed as a <see langword="float"/>.
- /// </exception>
- public static float GetAttributeFloat(this XmlReader reader, string attributeName)
- {
- string value = reader.GetAttribute(attributeName);
- if (value == null)
- {
- throw new XmlException($"Required attribute '{attributeName}' is missing.");
- }
- try
- {
- return float.Parse(value);
- }
- catch (Exception ex) when (ex is FormatException || ex is OverflowException)
- {
- throw new XmlException(
- $"Invalid float format for attribute '{attributeName}'. Expected float, but got '{value}'",
- ex
- );
- }
- }
- /// <summary>
- /// Reads an XML attribute as a <see langword="float"/> value, returning a default value if the attribute is missing or invalid.
- /// </summary>
- /// <param name="reader">The XML reader instance.</param>
- /// <param name="attributeName">The name of the attribute to read.</param>
- /// <param name="defaultValue">The default value to return if the attribute is missing or cannot be parsed.</param>
- /// <returns>The <see langword="float"/> value parsed from the specified attribute, or the default value if parsing fails.</returns>
- public static float GetAttributeFloat(this XmlReader reader, string attributeName, float defaultValue)
- {
- string value = reader.GetAttribute(attributeName);
- if (value == null)
- {
- return defaultValue;
- }
- try
- {
- return float.Parse(value);
- }
- catch
- {
- return defaultValue;
- }
- }
- /// <summary>
- /// Reads an XML attribute as a <see langword="bool"/> value.
- /// </summary>
- /// <param name="reader">The XML reader instance.</param>
- /// <param name="attributeName">The name of the attribute to read.</param>
- /// <returns>The <see langword="bool"/> value parsed from the value of the specified attribute.</returns>
- /// <exception cref="XmlException">
- /// Thrown when the attribute is missing, or when the attribute value cannot be parsed as a <see langword="bool"/>.
- /// </exception>
- public static bool GetAttributeBool(this XmlReader reader, string attributeName)
- {
- string value = reader.GetAttribute(attributeName);
- if (value == null)
- {
- throw new XmlException($"Required attribute '{attributeName}' is missing.");
- }
- try
- {
- return bool.Parse(value);
- }
- catch (Exception ex) when (ex is FormatException)
- {
- throw new XmlException(
- $"Invalid bool format for attribute '{attributeName}'. Expected 'true' or 'false' but got '{value}'",
- ex
- );
- }
- }
- /// <summary>
- /// Reads an XML attribute as a <see langword="bool"/> value, returning a default value if the attribute is missing or invalid.
- /// </summary>
- /// <param name="reader">The XML reader instance.</param>
- /// <param name="attributeName">The name of the attribute to read.</param>
- /// <param name="defaultValue">The default value to return if the attribute is missing or cannot be parsed.</param>
- /// <returns>The <see langword="bool"/> value parsed from the value of the specified attribute, or the default value if parsing fails.</returns>
- public static bool GetAttributeBool(this XmlReader reader, string attributeName, bool defaultValue)
- {
- string value = reader.GetAttribute(attributeName);
- if (value == null)
- {
- return defaultValue;
- }
- try
- {
- return bool.Parse(value);
- }
- catch
- {
- return defaultValue;
- }
- }
- /// <summary>
- /// Reads an XML attribute as an enumeration value.
- /// </summary>
- /// <typeparam name="T">The enumeration type to parse.</typeparam>
- /// <param name="reader">The XML reader instance.</param>
- /// <param name="attributeName">The name of the attribute to read.</param>
- /// <returns>The enumeration value parsed from the value of the specified attribute.</returns>
- /// <exception cref="XmlException">
- /// Thrown when the attribute is missing, or when the attribute value cannot be parsed as the specified enumeration type.
- /// </exception>
- public static T GetAttributeEnum<T>(this XmlReader reader, string attributeName) where T : struct, Enum
- {
- string value = reader.GetAttribute(attributeName);
- if (value == null)
- {
- throw new XmlException($"Required attribute '{attributeName}' is missing.");
- }
- try
- {
- return Enum.Parse<T>(value);
- }
- catch (Exception ex) when (ex is ArgumentException)
- {
- throw new XmlException(
- $"Invalid {typeof(T).Name} format for attribute '{attributeName}'. Expected a {typeof(T).Name} value but got '{value}'",
- ex
- );
- }
- }
- /// <summary>
- /// Reads an XML attribute as an enumeration value, returning a default value if the attribute is missing or invalid.
- /// </summary>
- /// <typeparam name="T">The enumeration type to parse.</typeparam>
- /// <param name="reader">The XML reader instance.</param>
- /// <param name="attributeName">The name of the attribute to read.</param>
- /// <param name="defaultValue">The default value to return if the attribute is missing or cannot be parsed.</param>
- /// <returns>The enumeration value parsed from the value of the specified attribute, or the default value if parsing fails.</returns>
- public static T GetAttributeEnum<T>(this XmlReader reader, string attributeName, T defaultValue) where T : struct, Enum
- {
- string value = reader.GetAttribute(attributeName);
- if (value == null)
- {
- return defaultValue;
- }
- try
- {
- return Enum.Parse<T>(value);
- }
- catch
- {
- return defaultValue;
- }
- }
- /// <summary>
- /// Reads an XML attribute as a <see cref="Rectangle"/> value.
- /// </summary>
- /// <param name="reader">The XML reader instance.</param>
- /// <param name="attributeName">The name of the attribute to read.</param>
- /// <returns>The <see cref="Rectangle"/> value parsed from the value of the specified attribute.</returns>
- /// <exception cref="XmlException">
- /// Thrown when the attribute is missing, or when the attribute value cannot be parsed as a <see cref="Rectangle"/>.
- /// </exception>
- public static Rectangle GetAttributeRectangle(this XmlReader reader, string attributeName)
- {
- string value = reader.GetAttribute(attributeName);
- if (value == null)
- {
- throw new XmlException($"Required attribute '{attributeName}' is missing.");
- }
- string[] split = value.Split(',', StringSplitOptions.RemoveEmptyEntries);
- try
- {
- if (split.Length != 4)
- {
- throw new InvalidOperationException($"{nameof(Rectangle)} attribute must contain four integer values separated by a comma");
- }
- int x = int.Parse(split[0]);
- int y = int.Parse(split[1]);
- int width = int.Parse(split[2]);
- int height = int.Parse(split[3]);
- return new Rectangle(x, y, width, height);
- }
- catch (Exception ex) when (ex is FormatException || ex is OverflowException || ex is InvalidOperationException)
- {
- throw new XmlException(
- $"Invalid {nameof(Rectangle)} format for attribute '{attributeName}'. Expected 'x,y,width,height' but got '{value}'",
- ex
- );
- }
- }
- /// <summary>
- /// Reads an XML attribute as a <see cref="Rectangle"/> value, returning a default value if the attribute is missing or invalid.
- /// </summary>
- /// <param name="reader">The XML reader instance.</param>
- /// <param name="attributeName">The name of the attribute to read.</param>
- /// <param name="defaultValue">The default value to return if the attribute is missing or cannot be parsed.</param>
- /// <returns>The <see cref="Rectangle"/> value parsed from the value of the specified attribute, or the default value if parsing fails.</returns>
- public static Rectangle GetAttributeRectangle(this XmlReader reader, string attributeName, Rectangle defaultValue)
- {
- string value = reader.GetAttribute(attributeName);
- if (value == null)
- {
- return defaultValue;
- }
- string[] split = value.Split(',', StringSplitOptions.RemoveEmptyEntries);
- try
- {
- if (split.Length != 4)
- {
- return defaultValue;
- }
- int x = int.Parse(split[0]);
- int y = int.Parse(split[1]);
- int width = int.Parse(split[2]);
- int height = int.Parse(split[3]);
- return new Rectangle(x, y, width, height);
- }
- catch
- {
- return defaultValue;
- }
- }
- /// <summary>
- /// Reads an XML attribute as a <see cref="Vector2"/> value.
- /// </summary>
- /// <param name="reader">The XML reader instance.</param>
- /// <param name="attributeName">The name of the attribute to read.</param>
- /// <returns>The <see cref="Vector2"/> value parsed from the value of the specified attribute.</returns>
- /// <exception cref="XmlException">
- /// Thrown when the attribute is missing, or when the attribute value cannot be parsed as a <see cref="Vector2"/>.
- /// </exception>
- public static Vector2 GetAttributeVector2(this XmlReader reader, string attributeName)
- {
- string value = reader.GetAttribute(attributeName);
- if (value == null)
- {
- throw new XmlException($"Required attribute '{attributeName}' is missing.");
- }
- string[] split = value.Split(',', StringSplitOptions.RemoveEmptyEntries);
- try
- {
- if (split.Length != 2)
- {
- throw new InvalidOperationException($"{nameof(Vector2)} attribute must contain two float values separated by a comma");
- }
- float x = float.Parse(split[0]);
- float y = float.Parse(split[1]);
- return new Vector2(x, y);
- }
- catch (Exception ex) when (ex is FormatException || ex is OverflowException || ex is InvalidOperationException)
- {
- throw new XmlException(
- $"Invalid {nameof(Vector2)} format for attribute '{attributeName}'. Expected 'x,y', but got '{value}'",
- ex
- );
- }
- }
- /// <summary>
- /// Reads an XML attribute as a <see cref="Vector2"/> value, returning a default value if the attribute is missing or invalid.
- /// </summary>
- /// <param name="reader">The XML reader instance.</param>
- /// <param name="attributeName">The name of the attribute to read.</param>
- /// <param name="defaultValue">The default value to return if the attribute is missing or cannot be parsed.</param>
- /// <returns>The <see cref="Vector2"/> value parsed from the value of the specified attribute, or the default value if parsing fails.</returns>
- public static Vector2 GetAttributeVector2(this XmlReader reader, string attributeName, Vector2 defaultValue)
- {
- string value = reader.GetAttribute(attributeName);
- if (value == null)
- {
- return defaultValue;
- }
- string[] split = value.Split(',', StringSplitOptions.RemoveEmptyEntries);
- try
- {
- if (split.Length != 2)
- {
- return defaultValue;
- }
- float x = float.Parse(split[0]);
- float y = float.Parse(split[1]);
- return new Vector2(x, y);
- }
- catch
- {
- return defaultValue;
- }
- }
- /// <summary>
- /// Reads an XML attribute as a <see cref="Vector3"/> value.
- /// </summary>
- /// <param name="reader">The XML reader instance.</param>
- /// <param name="attributeName">The name of the attribute to read.</param>
- /// <returns>The <see cref="Vector3"/> value parsed from the value of the specified attribute.</returns>
- /// <exception cref="XmlException">
- /// Thrown when the attribute is missing, or when the attribute value cannot be parsed as a <see cref="Vector3"/>.
- /// </exception>
- public static Vector3 GetAttributeVector3(this XmlReader reader, string attributeName)
- {
- string value = reader.GetAttribute(attributeName);
- if (value == null)
- {
- throw new XmlException($"Required attribute '{attributeName}' is missing.");
- }
- string[] split = value.Split(',', StringSplitOptions.RemoveEmptyEntries);
- try
- {
- if (split.Length != 3)
- {
- throw new InvalidOperationException($"{nameof(Vector3)} attribute must contain three float values separated by a comma");
- }
- float x = float.Parse(split[0]);
- float y = float.Parse(split[1]);
- float z = float.Parse(split[2]);
- return new Vector3(x, y, z);
- }
- catch (Exception ex) when (ex is FormatException || ex is OverflowException || ex is InvalidOperationException)
- {
- throw new XmlException(
- $"Invalid {nameof(Vector3)} format for attribute '{attributeName}'. Expected 'x,y,z', but got '{value}'",
- ex
- );
- }
- }
- /// <summary>
- /// Reads an XML attribute as a <see cref="Vector3"/> value, returning a default value if the attribute is missing or invalid.
- /// </summary>
- /// <param name="reader">The XML reader instance.</param>
- /// <param name="attributeName">The name of the attribute to read.</param>
- /// <param name="defaultValue">The default value to return if the attribute is missing or cannot be parsed.</param>
- /// <returns>The <see cref="Vector3"/> value parsed from the value of the specified attribute, or the default value if parsing fails.</returns>
- public static Vector3 GetAttributeVector3(this XmlReader reader, string attributeName, Vector3 defaultValue)
- {
- string value = reader.GetAttribute(attributeName);
- if (value == null)
- {
- return defaultValue;
- }
- string[] split = value.Split(',', StringSplitOptions.RemoveEmptyEntries);
- try
- {
- if (split.Length != 3)
- {
- return defaultValue;
- }
- float x = float.Parse(split[0]);
- float y = float.Parse(split[1]);
- float z = float.Parse(split[2]);
- return new Vector3(x, y, z);
- }
- catch
- {
- return defaultValue;
- }
- }
- }
|