XML解析器想不明白的ASP指令:<%@ <%=等
你可能最好使用正則表達式來做到這一點,可能會在3個階段。
- 匹配整個頁面的任何標籤元素。
- 對於每個標籤,匹配標籤和控制類型。
- 對於每個匹配(2)的標籤,匹配任何屬性。
所以,從頂部開始,我們可以使用下面的正則表達式:
(?<tag><[^%/](?:.*?)>)
這將匹配沒有<%和<任何標籤/和不那麼懶洋洋地(我們不」不要貪婪的表達,因爲我們不會正確讀取內容)。下面可以匹配:
<asp:Content ID="ph_PageContent" ContentPlaceHolderID="ph_MainContent" runat="server">
<asp:Image runat="server" />
<img src="/test.png" />
對於每一個被俘虜的標籤,我們要然後提取標籤和類型:
<(?<tag>[a-z][a-z1-9]*):(?<type>[a-z][a-z1-9]*)
創建命名捕捉組,使這更容易,這將讓我們輕鬆提取標籤和類型。這隻會匹配服務器標籤,因此標準的html標籤將在此時被刪除。
<asp:Content ID="ph_PageContent" ContentPlaceHolderID="ph_MainContent" runat="server">
將產生:
{ tag = "asp", type = "Content" }
用相同的標籤,我們可以匹配任何屬性:
(?<name>\S+)=["']?(?<value>(?:.(?!["']?\s+(?:\S+)=|[>"']))+.)["']?
其中產量:
{ name = "ID", value = "ph_PageContent" },
{ name = "ContentPlaceHolderID", value = "ph_MainContent" },
{ name = "runat", value = "server" }
所以把所有的在一起,我們可以創建一個快速的功能能爲我們創造一個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;
}
得到的文件看起來是這樣的:
<controls>
<control>
<tag>asp</tag>
<type>Content</type>
<attributes>
<ID>ph_PageContent</ID>
<ContentPlaceHolderID>ph_MainContent</ContentPlaceHolderID>
<runat>server</runat>
</attributes>
</control>
</controls>
希望幫助!
你說的意思是「本」在你的最後一個問題(「此外,是否有這方面的任何可用的庫?」)?解析XML( - >是,有(堆)庫)或在(有效的)ASPX文件中找到控件( - >不太確定是否有庫)。 – scherand 2010-06-04 08:27:13
「我」的意思是,任何已有的庫都可以直接完成這個任務,而不是我爲它編寫邏輯。 – Ubaid 2010-06-04 08:36:30