Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
01401f0
Add support for repeated XML elements without a name attribute
amoerie Nov 12, 2020
f83dcfe
Disable tests for duplicate handling in XML config, they are incompat…
amoerie Nov 13, 2020
8de7bda
Stop using the 'Name' parameter to use arrays in XML in the tests, th…
amoerie Nov 13, 2020
96ea0b9
Merge branch 'master' of github.com:dotnet/runtime into repeatedeleme…
amoerie Dec 17, 2020
ca7097a
Rework the XML configuration provider
amoerie Dec 18, 2020
c601197
Add test that verifies mixing repeated with non-repeated XML elements…
amoerie Dec 18, 2020
3dddfca
Cleanup nullable annotations in XmlConfigurationElement
amoerie Feb 5, 2021
5b55a5f
Use ordinal ignore case when detecting siblings in XML configuration
amoerie Feb 5, 2021
cd11a03
Remove empty line
amoerie Feb 5, 2021
ff2336f
Remove usage of Linq method '.Any()'
amoerie Feb 5, 2021
de44ff0
Remove dependency on System.Linq in XmlStreamConfigurationProvider
amoerie Feb 5, 2021
2f77e01
Simplify check that detects whether the current element is the root e…
amoerie Feb 5, 2021
5999c1c
Merge branch 'master' of github.com:dotnet/runtime into repeatedeleme…
amoerie Feb 5, 2021
9a1af2a
Apply suggestions from code review
amoerie Feb 8, 2021
6f07563
Add test for array simulation using Name attribute
amoerie Feb 8, 2021
e479aa9
Add tests related to case insensitivity in XML configuration keys
amoerie Feb 8, 2021
f2e56ee
Merge master and resolve conflicts
amoerie Feb 8, 2021
8901143
Improve performance of XML configuration provider
amoerie Feb 28, 2021
862244e
Revert accidental change of solution file
amoerie Mar 1, 2021
49024de
Merge branch 'main' into repeatedelementsinxmlconfig
amoerie Mar 1, 2021
2c2f1b3
Apply suggestion from feedback: simplify children list initialization
amoerie Mar 10, 2021
22c02e8
Rename ProcessAttributes -> ReadAttributes when parsing the XML
amoerie Mar 10, 2021
5a60973
Merge branch 'main' of github.com:dotnet/runtime into repeatedelement…
amoerie Mar 10, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Rework the XML configuration provider
The XML configuration provider now builds a simple in-memory model of the XML elements that it encounters
Each element keeps track of its attributes, children and content.
Furthermore, each element also has a reference to its siblings.
Each group of siblings all share the same list.

All of the above makes it possible to intelligently produce configuration keys and values, taking into account repeated XML elements.
  • Loading branch information
amoerie committed Dec 18, 2020
commit ca7097a0ae69a26391f9f351f8e800f3589ae4a0

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Microsoft.Extensions.Configuration.Xml
{
Expand All @@ -16,55 +14,41 @@ internal class XmlConfigurationElement

public string LineInfo { get; }

public bool Multiple { get; set; }

public int Index { get; set; }
/// <summary>
/// The children of this element
/// </summary>
public List<XmlConfigurationElement>? Children { get; set; }

/// <summary>
/// The parent element, or null if this is the root element
/// The siblings of this element, including itself
/// Elements are considered siblings if they share the same element name and name attribute
/// This list is shared by each sibling
/// </summary>
public XmlConfigurationElement Parent { get; }
public List<XmlConfigurationElement>? Siblings { get; set; }

public XmlConfigurationElementTextContent? TextContent { get; set; }

public XmlConfigurationElement(XmlConfigurationElement parent, string elementName, string name, string lineInfo)
public List<XmlConfigurationElementAttributeValue>? Attributes { get; set; }

public XmlConfigurationElement(string elementName, string name, string lineInfo)
{
Parent = parent;
ElementName = elementName ?? throw new ArgumentNullException(nameof(elementName));
Name = name;
LineInfo = lineInfo;
Children = null;
Siblings = null;
TextContent = null;
Attributes = null;
}

public string Key
{
get
{
var tokens = new List<string>(3);

// the root element does not contribute to the prefix
if (Parent != null) tokens.Add(ElementName);

// the name attribute always contributes to the prefix
if (Name != null) tokens.Add(Name);

// the index only contributes to the prefix when there are multiple elements wih the same name
if (Multiple) tokens.Add(Index.ToString());

// the root element without a name attribute does not contribute to prefix at all
if (!tokens.Any()) return null;

return string.Join(ConfigurationPath.KeyDelimiter, tokens);
}
}

public bool IsSibling(XmlConfigurationElement xmlConfigurationElement)
public bool IsSiblingOf(XmlConfigurationElement xmlConfigurationElement)
{
if (xmlConfigurationElement is null)
{
throw new ArgumentNullException(nameof(xmlConfigurationElement));
}

return Parent != null
&& xmlConfigurationElement.Parent == Parent
&& string.Equals(ElementName, xmlConfigurationElement.ElementName)
return string.Equals(ElementName, xmlConfigurationElement.ElementName)
&& string.Equals(Name, xmlConfigurationElement.Name);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,19 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.Linq;

namespace Microsoft.Extensions.Configuration.Xml
{
internal class XmlConfigurationElementAttributeValue : IXmlConfigurationValue
internal class XmlConfigurationElementAttributeValue
{
private readonly XmlConfigurationElement[] _elementPath;
private readonly string _attribute;

public XmlConfigurationElementAttributeValue(Stack<XmlConfigurationElement> elementPath, string attribute, string value, string lineInfo)
public XmlConfigurationElementAttributeValue(string attribute, string value, string lineInfo)
{
_elementPath = elementPath?.Reverse()?.ToArray() ?? throw new ArgumentNullException(nameof(elementPath));
_attribute = attribute ?? throw new ArgumentNullException(nameof(attribute));
Attribute = attribute ?? throw new ArgumentNullException(nameof(attribute));
Value = value ?? throw new ArgumentNullException(nameof(value));
LineInfo = lineInfo;
}

/// <summary>
/// Combines the path to this element with the attribute value to produce a key.
/// Note that this property cannot be computed during construction,
/// because the keys of the elements along the path may change when multiple elements with the same name are encountered
/// </summary>
public string Key => ConfigurationPath.Combine(_elementPath.Select(e => e.Key).Concat(new[] { _attribute }).Where(key => key != null));
public string Attribute { get; }

public string Value { get; }

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;

namespace Microsoft.Extensions.Configuration.Xml
{
internal class XmlConfigurationElementTextContent
{
public XmlConfigurationElementTextContent(string textContent, string lineInfo)
{
TextContent = textContent ?? throw new ArgumentNullException(nameof(textContent));
LineInfo = lineInfo ?? throw new ArgumentNullException(nameof(lineInfo));
}

public string TextContent { get; }

public string LineInfo { get; }
}
}
Loading