2

署名が次のようなサードパーティ 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>

たとえば、[行 7、列 12] から [行 9、列 25] までロードする XamlXmlReader を API に提供する必要があります。

<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 に精通していませIXamlLineInfoXamlXmlReaderSettings.ProvideLineInfo)

ありがとう

4

1 に答える 1

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 に追加したいものを簡単にクエリできます。

于 2014-02-03T01:21:51.040 に答える