Skip to content

Instantly share code, notes, and snippets.

@deanebarker
Last active October 11, 2021 18:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save deanebarker/3618faff0b743e351b2afb3adaf5f566 to your computer and use it in GitHub Desktop.
Save deanebarker/3618faff0b743e351b2afb3adaf5f566 to your computer and use it in GitHub Desktop.
An custom value type for Fluid that allows for easy access of XML element content
<people>
<person>
<name prefix="Mr">
<first>Deane</first>
<last>Barker</last>
</name>
</person>
<person>
<name prefix="Mrs">
<first>Annie</first>
<last>Barker</last>
</name>
</person>
</people>
* Mr Deane Barker
* Mrs Annie Barker
{% for person in people._children %}
* {{ person.name._attrs.prefix }} {{ person.name.first._text }} {{ person.name.last._text }}
{% endfor %}
public class XmlValue : FluidValue
{
// The accessor to retrieve the text content of an element
public static string TextAccessor { get; set; } = "_text";
// The accessor to retrieve a dictionary of attributes of an element
public static string AttributesAccessor { get; set; } = "_attrs";
// The accessor to retrieve an array of the children of an element
public static string ChildrenAccessor { get; set; } = "_children";
private XElement _xml;
public XmlValue(XElement xml)
{
_xml = xml;
}
public XmlValue(XDocument xml)
{
_xml = xml.Root;
}
protected override FluidValue GetValue(string name, TemplateContext context)
{
if (name == XmlValue.TextAccessor)
{
return StringValue.Create(ToStringValue());
}
if (name == AttributesAccessor)
{
return new DictionaryValue(new FluidValueDictionaryFluidIndexable(_xml.Attributes().ToDictionary(a => a.Name.ToString(), a => (FluidValue)StringValue.Create(a.Value))));
}
if (name == ChildrenAccessor)
{
return new ArrayValue(_xml.Elements().Select(e => new XmlValue(e)).ToArray());
}
var subElement = _xml.Element(name);
return subElement != null
? new XmlValue(_xml.Element(name))
: NilValue.Instance;
}
public override FluidValues Type => FluidValues.Object;
public override bool Equals(FluidValue other) => false;
public override bool ToBooleanValue() => false;
public override decimal ToNumberValue() => 0;
public override object ToObjectValue() => _xml;
public override string ToStringValue() => _xml.Value;
public override void WriteTo(TextWriter writer, TextEncoder encoder, CultureInfo cultureInfo) { }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment