Чтение от строки X до строки Y из Xaml с помощью XamlXmlReader

Я пытаюсь вызвать метод API третьей части, подпись которого выглядит

object Load(XamlXmlReader reader);

Затем с учетом этого образца XAML

<Foo xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:barns="clr-namespace:Bar;assembly=Bar"
    Property="Value">
    <Root>
        <Element1 />
        <Element2>
            <SubElement>
                <barns:Sample />
            </SubElement>
        </Element2>
    </Root>
</Foo>

Мне нужно, чтобы предоставить API XamlXmlReader, который загружается, скажем, с [строка 7, столбец 12] до [строка 9, столбец 25]

<SubElement>
    <barns:Sample />
</SubElement>

Окончательный Xaml, прочитанный читателем, должен быть

<Foo xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:barns="clr-namespace:Bar;assembly=Bar"
    Property="Value">
        <SubElement>
            <barns:Sample />
        </SubElement>
</Foo>

Есть ли функция, которая делает это чтение? Если мне нужно накатить свои собственные предложения или ресурсы, помимо создания другого файла с этим содержимым вручную из необработанной строки, это может помочь?(Я не знаком с XamlXmlReader) IXamlLineInfo а также XamlXmlReaderSettings.ProvideLineInfo около?

Спасибо

1 ответ

Это решение, которое я нашел, оно использует linq to XML, не стесняйтесь предлагать улучшения.

    public static XDocument CreateDocumentForLocation(Stream stream, Location targetLocation)
    {
        stream.Seek(0, 0);
        XElement root;
        List<XNode> nodesInLocation;
        XNamespace x = "http://schemas.microsoft.com/winfx/2006/xaml";
        using (var xmlReader = XmlReader.Create(stream, new XmlReaderSettings { 
            CloseInput = false }))
        {
            XDocument doc = XDocument.Load(xmlReader, 
                LoadOptions.SetLineInfo | LoadOptions.PreserveWhitespace);

            root = doc.Root;
            nodesInLocation = doc.Root.DescendantNodes()
                .Where(node => IsInside(node, targetLocation))
                .ToList();
        }

        root.RemoveNodes();
        XDocument trimmedDocument = XDocument.Load(root.CreateReader());
        trimmedDocument.Root.Add(nodesInLocation.FirstOrDefault());

        return trimmedDocument;
    }

    public static bool IsInside(XNode node, Location targetLocation)
    {
        var lineInfo = (IXmlLineInfo)node;
        return (lineInfo.LineNumber > targetLocation.StartLine && lineInfo.LineNumber < targetLocation.EndLine) // middle
            || (lineInfo.LineNumber == targetLocation.StartLine && lineInfo.LinePosition >= targetLocation.StartColumn) // first line after start column
            || (lineInfo.LineNumber == targetLocation.EndLine && lineInfo.LinePosition <= targetLocation.EndColumn); // last line until last column
    }

Мне нужно было вставить некоторые другие элементы в XML в моем приложении. Это основной фрагмент, вы сможете использовать linq to xml для простого запроса всего, что хотите добавить в окончательный XML.

Другие вопросы по тегам