解析aspx文件中的控件并将其转换为xml

Uba*_*aid 2 c# xml asp.net

我需要解析aspx文件(从磁盘,而不是在浏览器上呈现的文件),并列出页面上存在的所有服务器端asp.net控件,然后从中创建一个xml文件.这将是最好的方式吗?此外,有没有可用的库?

例如,如果我的aspx文件包含

<asp:label ID="lbl1" runat="server" Text="Hi"></asp:label>

我的xml文件是

<controls>
<ID>lbl1</ID>
<runat>server</runat>
<Text>Hi</Text>
</controls>

Mat*_*ott 5

Xml解析器无法理解ASP指令:<%@ <%=等.

您可能最好使用正则表达式来完成此操作,可能分为3个阶段.

  1. 匹配整个页面中的任何标记元素.
  2. 对于每个标记,匹配标记和控件类型.
  3. 对于匹配(2)的每个标记,匹配任何属性.

所以,从顶部开始,我们可以使用以下正则表达式:

(?<tag><[^%/](?:.*?)>)
Run Code Online (Sandbox Code Playgroud)

这将匹配任何没有<%和</并且懒惰的标签(我们不想要贪婪的表达式,因为我们不会正确读取内容).以下内容可以匹配:

<asp:Content ID="ph_PageContent" ContentPlaceHolderID="ph_MainContent" runat="server">
<asp:Image runat="server" />
<img src="/test.png" />
Run Code Online (Sandbox Code Playgroud)

对于每个捕获的标记,我们希望然后提取标记并键入:

<(?<tag>[a-z][a-z1-9]*):(?<type>[a-z][a-z1-9]*)
Run Code Online (Sandbox Code Playgroud)

创建命名捕获组使这更容易,这将允许我们轻松提取标记和类型.这只会匹配服务器标签,因此此时将删除标准html标签.

<asp:Content ID="ph_PageContent" ContentPlaceHolderID="ph_MainContent" runat="server">
Run Code Online (Sandbox Code Playgroud)

将产量:

{ tag = "asp", type = "Content" }
Run Code Online (Sandbox Code Playgroud)

使用相同的标记,我们可以匹配任何属性:

(?<name>\S+)=["']?(?<value>(?:.(?!["']?\s+(?:\S+)=|[>"']))+.)["']?
Run Code Online (Sandbox Code Playgroud)

产量:

{ name = "ID", value = "ph_PageContent" },
{ name = "ContentPlaceHolderID", value = "ph_MainContent" },
{ name = "runat", value = "server" }
Run Code Online (Sandbox Code Playgroud)

所以把它们放在一起,我们可以创建一个可以为我们创建XmlDocument的快速函数:

public XmlDocument CreateDocumentFromMarkup(string content)
{
  if (string.IsNullOrEmpty(content))
    throw new ArgumentException("'content' must have a value.", "content");

  RegexOptions options = RegexOptions.CultureInvariant | RegexOptions.Compiled | RegexOptions.IgnoreCase;
  Regex tagExpr = new Regex("(?<tag><[^%/](?:.*?)>)", options);
  Regex serverTagExpr = new Regex("<(?<tag>[a-z][a-z1-9]*):(?<type>[a-z][a-z1-9]*)", options);
  Regex attributeExpr = new Regex("(?<name>\\S+)=[\"']?(?<value>(?:.(?![\"']?\\s+(?:\\S+)=|[>\"']))+.)[\"']?", options);

  XmlDocument document = new XmlDocument();
  XmlElement root = document.CreateElement("controls");

  Func<XmlDocument, string, string, XmlElement> creator = (document, name, value) => {
    XmlElement element = document.CreateElement(name);
    element.InnerText = value;

    return element;
  };

  foreach (Match tagMatch in tagExpr.Matches(content)) {
    Match serverTagMatch = serverTagExpr.Match(tagMatch.Value);

    if (serverTagMatch.Success) {
      XmlElement controlElement = document.CreateElement("control");

      controlElement.AppendChild(
        creator(document, "tag", serverTagMatch.Groups["tag"].Value));
      controlElement.AppendChild(
        creator(document, "type", serverTagMatch.Groups["type"].Value));


      XmlElement attributeElement = document.CreateElement("attributes");

      foreach (Match attributeMatch in attributeExpr.Matches(tagMatch.Value)) {
        if (attributeMatch.Success) {
          attributeElement.AppendChild(
            creator(document, attributeMatch.Groups["name"].Value, attributeMatch.Groups["value"].Value));
        }
      }

      controlElement.AppendChild(attributeElement);
      root.AppendChild(controlElement);
    }
  }  

  return document;
}
Run Code Online (Sandbox Code Playgroud)

生成的文档可能如下所示:

<controls>
  <control>
    <tag>asp</tag>
    <type>Content</type>
    <attributes>
      <ID>ph_PageContent</ID>
      <ContentPlaceHolderID>ph_MainContent</ContentPlaceHolderID>
      <runat>server</runat>
    </attributes>
  </control>
</controls>
Run Code Online (Sandbox Code Playgroud)

希望有所帮助!