2014-01-23 16 views
2

我想调用的签名看起来像从线X读,直到线Y在XAML与XamlXmlReader

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方法给api提供一个XamlXmlReader,可以说[行7,第12列]直到[行9,列25]

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

最终的XAML中由读者readed应该

<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

感谢

回答

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中的内容。