This commit is contained in:
headhunter45_cp
2010-09-26 06:31:06 +00:00
parent dfa1aeb1b9
commit d280868fc8
31 changed files with 1945 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<TestRunConfiguration name="Local Test Run" id="dda1f1a0-63d3-4697-9b76-0ff7ce7b82b7" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2006">
<Description>This is a default test run configuration for a local test run.</Description>
<TestTypeSpecific />
</TestRunConfiguration>

View File

@@ -0,0 +1,73 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plan B Html Parser", "Plan B Html Parser\Plan B Html Parser.csproj", "{A6FA0455-ACB5-4E80-9E58-6B79976AA717}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestProject1", "TestProject1\TestProject1.csproj", "{9E7D5692-C2E9-4219-977E-143CC75B5737}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{AD007B35-38A3-47C0-B9DE-A1805B67270C}"
ProjectSection(SolutionItems) = preProject
LocalTestRun.testrunconfig = LocalTestRun.testrunconfig
Plan B Html Parser.vsmdi = Plan B Html Parser.vsmdi
EndProjectSection
EndProject
Global
GlobalSection(TeamFoundationVersionControl) = preSolution
SccNumberOfProjects = 4
SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
SccTeamFoundationServer = https://tfs.codeplex.com/tfs/TFS14
SccLocalPath0 = .
SccProjectUniqueName1 = Plan\u0020B\u0020Html\u0020Parser\\Content\\Content.contentproj
SccProjectTopLevelParentUniqueName1 = Plan\u0020B\u0020Html\u0020Parser\\Plan\u0020B\u0020Html\u0020Parser.csproj
SccProjectName1 = Plan\u0020B\u0020Html\u0020Parser/Content
SccLocalPath1 = Plan\u0020B\u0020Html\u0020Parser\\Content
SccProjectUniqueName2 = Plan\u0020B\u0020Html\u0020Parser\\Plan\u0020B\u0020Html\u0020Parser.csproj
SccProjectName2 = Plan\u0020B\u0020Html\u0020Parser
SccLocalPath2 = Plan\u0020B\u0020Html\u0020Parser
SccProjectUniqueName3 = TestProject1\\TestProject1.csproj
SccProjectName3 = TestProject1
SccLocalPath3 = TestProject1
EndGlobalSection
GlobalSection(TestCaseManagementSettings) = postSolution
CategoryFile = Plan B Html Parser.vsmdi
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A6FA0455-ACB5-4E80-9E58-6B79976AA717}.Debug|Any CPU.ActiveCfg = Debug|x86
{A6FA0455-ACB5-4E80-9E58-6B79976AA717}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{A6FA0455-ACB5-4E80-9E58-6B79976AA717}.Debug|Mixed Platforms.Build.0 = Debug|x86
{A6FA0455-ACB5-4E80-9E58-6B79976AA717}.Debug|x86.ActiveCfg = Debug|x86
{A6FA0455-ACB5-4E80-9E58-6B79976AA717}.Debug|x86.Build.0 = Debug|x86
{A6FA0455-ACB5-4E80-9E58-6B79976AA717}.Release|Any CPU.ActiveCfg = Release|x86
{A6FA0455-ACB5-4E80-9E58-6B79976AA717}.Release|Mixed Platforms.ActiveCfg = Release|x86
{A6FA0455-ACB5-4E80-9E58-6B79976AA717}.Release|Mixed Platforms.Build.0 = Release|x86
{A6FA0455-ACB5-4E80-9E58-6B79976AA717}.Release|x86.ActiveCfg = Release|x86
{A6FA0455-ACB5-4E80-9E58-6B79976AA717}.Release|x86.Build.0 = Release|x86
{9E7D5692-C2E9-4219-977E-143CC75B5737}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9E7D5692-C2E9-4219-977E-143CC75B5737}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9E7D5692-C2E9-4219-977E-143CC75B5737}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{9E7D5692-C2E9-4219-977E-143CC75B5737}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{9E7D5692-C2E9-4219-977E-143CC75B5737}.Debug|x86.ActiveCfg = Debug|Any CPU
{9E7D5692-C2E9-4219-977E-143CC75B5737}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9E7D5692-C2E9-4219-977E-143CC75B5737}.Release|Any CPU.Build.0 = Release|Any CPU
{9E7D5692-C2E9-4219-977E-143CC75B5737}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{9E7D5692-C2E9-4219-977E-143CC75B5737}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{9E7D5692-C2E9-4219-977E-143CC75B5737}.Release|x86.ActiveCfg = Release|Any CPU
{730F03D9-CB96-43A9-88E3-A8687A66CF5E}.Debug|Any CPU.ActiveCfg = Debug|x86
{730F03D9-CB96-43A9-88E3-A8687A66CF5E}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{730F03D9-CB96-43A9-88E3-A8687A66CF5E}.Debug|x86.ActiveCfg = Debug|x86
{730F03D9-CB96-43A9-88E3-A8687A66CF5E}.Release|Any CPU.ActiveCfg = Release|x86
{730F03D9-CB96-43A9-88E3-A8687A66CF5E}.Release|Mixed Platforms.ActiveCfg = Release|x86
{730F03D9-CB96-43A9-88E3-A8687A66CF5E}.Release|x86.ActiveCfg = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<TestLists xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2006">
<TestList name="Lists of Tests" id="8c43106b-9dc1-4907-a29f-aa66a61bf5b6">
<RunConfiguration id="dda1f1a0-63d3-4697-9b76-0ff7ce7b82b7" name="Local Test Run" storage="localtestrun.testrunconfig" type="Microsoft.VisualStudio.TestTools.Common.TestRunConfiguration, Microsoft.VisualStudio.QualityTools.Common, PublicKeyToken=b03f5f7f11d50a3a" />
</TestList>
</TestLists>

View File

@@ -0,0 +1,10 @@
""
{
"FILE_VERSION" = "9237"
"ENLISTMENT_CHOICE" = "NEVER"
"PROJECT_FILE_RELATIVE_PATH" = ""
"NUMBER_OF_EXCLUDED_FILES" = "0"
"ORIGINAL_PROJECT_FILE_PATH" = ""
"NUMBER_OF_NESTED_PROJECTS" = "0"
"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROJECT"
}

View File

@@ -0,0 +1,52 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<ProjectGuid>730f03d9-cb96-43a9-88e3-a8687a66cf5e</ProjectGuid>
<ProjectTypeGuids>{96E2B04D-8817-42c6-938A-82C39BA4D311};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<XnaFrameworkVersion>v3.1</XnaFrameworkVersion>
<PlatformTarget>x86</PlatformTarget>
<OutputPath>bin\$(Platform)\$(Configuration)</OutputPath>
<SccProjectName>SAK</SccProjectName>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<XnaPlatform>Windows</XnaPlatform>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<XnaPlatform>Windows</XnaPlatform>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.EffectImporter, Version=3.1.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.FBXImporter, Version=3.1.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.TextureImporter, Version=3.1.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.XImporter, Version=3.1.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.AudioImporters, Version=3.1.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.VideoImporters, Version=3.1.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\$(XnaFrameworkVersion)\Microsoft.Xna.GameStudio.ContentPipeline.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,10 @@
""
{
"FILE_VERSION" = "9237"
"ENLISTMENT_CHOICE" = "NEVER"
"PROJECT_FILE_RELATIVE_PATH" = ""
"NUMBER_OF_EXCLUDED_FILES" = "0"
"ORIGINAL_PROJECT_FILE_PATH" = ""
"NUMBER_OF_NESTED_PROJECTS" = "0"
"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
}

View File

@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PlanB.Html.Nodes
{
public class HtmlBrNode: HtmlNode
{
public override string ToString()
{
return Environment.NewLine;
}
public HtmlBrNode()
{
Type = HtmlNodeType.Br;
}
public override string TagName
{
get { return StaticTagName; }
}
public static string StaticTagName
{
get { return "br"; }
}
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PlanB.Html.Nodes
{
public class HtmlDivNode: HtmlNode
{
public static string StaticTagName { get { return "div"; } }
public override string TagName { get { return StaticTagName; } }
}
}

View File

@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PlanB.Html.Nodes
{
public class HtmlDocumentNode: HtmlNode
{
public HtmlDocumentNode()
{
Type = HtmlNodeType.Document_;
}
public override string InnerHtml
{
get
{
StringBuilder sb = new StringBuilder();
foreach (HtmlNode child in Children)
{
sb.Append(child.OuterHtml);
}
return sb.ToString();
}
}
public override string OuterHtml
{
get
{
return InnerHtml;
}
}
public override string TagName
{
get { return "_Document"; }
}
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PlanB.Html.Nodes
{
public class HtmlImgNode: HtmlNode
{
public static string StaticTagName { get { return "img"; } }
public override string TagName { get { return StaticTagName; } }
}
}

View File

@@ -0,0 +1,191 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PlanB.Html.Nodes
{
public abstract class HtmlNode
{
public List<HtmlNode> Children { get; set; }
public HtmlNodeType Type { get; protected set; }
public List<KeyValuePair<string, string>> Attributes { get; set; }
public List<KeyValuePair<string, string>> Styles { get; set; }
public HtmlNode()
{
Attributes = new List<KeyValuePair<string, string>>();
Children = new List<HtmlNode>();
Styles = new List<KeyValuePair<string, string>>();
}
public virtual String InnerHtml
{
get
{
StringBuilder sb = new StringBuilder();
foreach (HtmlNode childNode in Children)
{
sb.Append(childNode.OuterHtml);
}
return sb.ToString();
}
}
public virtual String OuterHtml
{
get
{
string styles = GetStylesString();
string attributes = GetAttributesString();
StringBuilder sb = new StringBuilder();
sb.Append("<");
sb.Append(TagName);
if (!String.IsNullOrEmpty(styles))
{
sb.Append(" ");
sb.Append(styles);
}
if (!String.IsNullOrEmpty(attributes))
{
sb.Append(" ");
sb.Append(attributes);
}
if (Children.Count > 0)
{
sb.Append(">");
sb.Append(InnerHtml);
sb.Append("</");
sb.Append(TagName);
sb.Append(">");
}
else
{
sb.Append(" />");
}
return sb.ToString();
}
}
public abstract String TagName{get;}
protected virtual String GetAttributesString()
{
int numAttributes = Attributes.Count;
if (numAttributes == 0)
{
return String.Empty;
}
else if (numAttributes == 1)
{
return Attributes[0].Key + "=\"" + Attributes[0].Value + "\"";
}
else
{
StringBuilder sb = new StringBuilder();
sb.Append(Attributes[0].Key + "=\"" + Attributes[0].Value + "\"");
foreach (KeyValuePair<string, string> attribute in Attributes.Skip(1))
{
sb.Append(" " + attribute.Key + "=\"" + attribute.Value + "\"");
}
return sb.ToString();
}
}
protected virtual String GetStylesString()
{
int numStyles = Styles.Count;
if (numStyles == 0)
{
return String.Empty;
}
else if (numStyles == 1)
{
return "style=\"" + Styles[0].Key + ":" + Styles[0].Value + ";\"";
}
else
{
StringBuilder sb = new StringBuilder();
sb.Append("style=\"" + Styles[0].Key + ":" + Styles[0].Value + ";\"");
foreach (KeyValuePair<string, string> style in Styles.Skip(1))
{
sb.Append(";" + style.Key + ":" + style.Value);
}
sb.Append("\"");
return sb.ToString();
}
}
public void AddAttribute(KeyValuePair<string, string> attribute)
{
KeyValuePair<string, string> newAttribute = new KeyValuePair<string, string>(attribute.Key.ToLower(), attribute.Value);
if (newAttribute.Key == "style")
{
ClearStyles();
String styleString = newAttribute.Value;
string[] stylePairStrings = styleString.Split(new char[] { ';' });
KeyValuePair<string, string> style;
foreach (string stylePairString in stylePairStrings)
{
string[] temp = stylePairString.Split(new char[] { ':' });
if (temp.Length == 1)
{
style = new KeyValuePair<string, string>(temp[0], String.Empty);
}
else if (temp.Length >= 2)
{
style = new KeyValuePair<string, string>(temp[0], temp[1]);
}
else
{
style = new KeyValuePair<string, string>();
}
if (!String.IsNullOrEmpty(style.Key))
{
AddStyle(style);
}
}
}
else
{
Attributes.RemoveAll(i => i.Key == newAttribute.Key);
Attributes.Add(newAttribute);
}
}
private void ClearStyles()
{
Styles.Clear();
}
public void AddStyle(KeyValuePair<string, string> style)
{
KeyValuePair<string, string> newStyle = new KeyValuePair<string,string>(style.Key.ToLower(), style.Value);
Styles.RemoveAll(i => i.Key == newStyle.Key);
Styles.Add(newStyle);
}
}
public enum HtmlNodeType { Document_, Text_, Br, Span, Img, Paragraph, Div }
}

View File

@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PlanB.Html.Nodes
{
public class HtmlSpanNode: HtmlNode
{
public HtmlSpanNode()
{
Type = HtmlNodeType.Span;
}
public HtmlSpanNode(String text)
:this()
{
Children.Add(new HtmlTextNode(text));
}
public HtmlSpanNode(IEnumerable<HtmlNode> children)
:this()
{
foreach (HtmlNode child in children)
{
Children.Add(child);
}
}
public override string TagName
{
get { return StaticTagName; }
}
public static string StaticTagName { get { return "span"; } }
}
}

View File

@@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace PlanB.Html.Nodes
{
public class HtmlTextNode: HtmlNode
{
public String Text { get; set; }
public override string ToString()
{
return Text;
}
public HtmlTextNode()
{
Text = String.Empty;
Type = HtmlNodeType.Text_;
}
public HtmlTextNode(String text)
{
Text = text;
Type = HtmlNodeType.Text_;
}
public override string InnerHtml
{
get
{
return String.Empty;
}
}
public override string OuterHtml
{
get
{
return Entitize(Text);
}
}
public override string TagName
{
get { return "_Text"; }
}
private string Entitize(string Text)
{
string temp = Text;
temp = temp.Replace("&", "&amp;");
temp = temp.Replace("<", "&lt;");
temp = temp.Replace(">", "&gt;");
temp = temp.Replace("\"", "&quot;");
return temp;
}
}
}

View File

@@ -0,0 +1,289 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using PlanB.Html.Nodes;
using System.Text;
using PlanB.Html.Tokens;
using System.Text.RegularExpressions;
namespace PlanB.Html
{
public class Parser
{
public static List<HtmlToken> Tokenize(string htmlText)
{
List<HtmlToken> tokens = new List<HtmlToken>();
int position = 0;
int startOfNextToken = htmlText.IndexOf("<");
//If the whole document is text then just create one HtmlTextToken
if (startOfNextToken == -1)
{
tokens.Add(new HtmlTextToken(htmlText));
return tokens;
}
while (startOfNextToken >= 0)
{
if (startOfNextToken > position)
{
tokens.Add(new HtmlTextToken(htmlText.Substring(position, startOfNextToken - position)));
}
//Identify the type of token we are aproaching
string tokenText = htmlText.Substring(startOfNextToken);
string tokenName = String.Empty;
Regex r = new Regex(@"<(?<tagName>/?\w+)((\s+)(?<attributeName>\w*)=\""(?<attributeValue>[^""]*)\"")*(\s*)(/)?(\s*)>");
r = new Regex(@"<(?<tagName>/?\w+)(((\s+((?<attributeName>\w+)=(""(?<attributeValue>[^""]*)""))\s*))|((\s+((?<attributeName>\w+)=('(?<attributeValue>[^']*)'))\s*))|((\s+((?<attributeName>\w+)=(?<attributeValue>[^\s>]*))\s*)))*\s*(/)?(\s*)>");
Match m = r.Match(tokenText);
Console.WriteLine(m.ToString());
tokenName = m.Groups["tagName"].Value;
if (tokenName == HtmlSpanNode.StaticTagName)//"span"
{
//TODO: Handle attributes
HtmlBeginSpanToken token = new HtmlBeginSpanToken();
token.AddAttributes(m);
tokens.Add(token);
position = htmlText.IndexOf(">", startOfNextToken) + 1;
startOfNextToken = htmlText.IndexOf("<", position);
}
else if (tokenName == "/" + HtmlSpanNode.StaticTagName)//"/span"
{
tokens.Add(new HtmlEndSpanToken());
position = htmlText.IndexOf(">", startOfNextToken) + 1;
startOfNextToken = htmlText.IndexOf("<", position);
}
else if (tokenName == HtmlBrNode.StaticTagName)//"br"
{
HtmlBrToken token = new HtmlBrToken();
token.AddAttributes(m);
tokens.Add(token);
position = htmlText.IndexOf(">", startOfNextToken) + 1;
startOfNextToken = htmlText.IndexOf("<", position);
}
else if(tokenName == HtmlDivNode.StaticTagName)//"div"
{
HtmlBeginDivToken token = new HtmlBeginDivToken();
token.AddAttributes(m);
tokens.Add(token);
position = htmlText.IndexOf(">", startOfNextToken) + 1;
startOfNextToken = htmlText.IndexOf("<", position);
}
else if (tokenName == "/" + HtmlDivNode.StaticTagName)//"/div"
{
tokens.Add(new HtmlEndDivToken());
position = htmlText.IndexOf(">", startOfNextToken) + 1;
startOfNextToken = htmlText.IndexOf("<", position);
}
else if (tokenName == HtmlImgNode.StaticTagName)//"img"
{
HtmlImgToken token = new HtmlImgToken();
token.AddAttributes(m);
tokens.Add(token);
position = htmlText.IndexOf(">", startOfNextToken) + 1;
startOfNextToken = htmlText.IndexOf("<", position);
}
else
{
position = startOfNextToken;
startOfNextToken = htmlText.IndexOf("<", startOfNextToken + 1);
}
}
if (htmlText.Length - 1 > position)
{
tokens.Add(new HtmlTextToken(htmlText.Substring(position)));
}
return tokens;
}
public static HtmlNode Parse(List<HtmlToken> tokens)
{
HtmlNode rootNode = new HtmlDocumentNode();
int position = 0;
GetContents(rootNode, tokens, ref position);
return rootNode;
}
private static void GetContents(HtmlNode parentNode, List<HtmlToken> tokens, ref int position)
{
HtmlToken currentToken;
bool throwExceptions = false;
HtmlTextToken textToken = null;
HtmlBrToken brToken = null;
HtmlBeginSpanToken beginSpanToken = null;
HtmlEndSpanToken endSpanToken = null;
HtmlBeginDivToken beginDivToken = null;
HtmlEndDivToken endDivToken = null;
HtmlImgToken imgToken = null;
currentToken = tokens[position];
while (currentToken != null)
{
textToken = currentToken as HtmlTextToken;
brToken = currentToken as HtmlBrToken;
beginSpanToken = currentToken as HtmlBeginSpanToken;
endSpanToken = currentToken as HtmlEndSpanToken;
beginDivToken = currentToken as HtmlBeginDivToken;
endDivToken = currentToken as HtmlEndDivToken;
imgToken = currentToken as HtmlImgToken;
if (textToken != null)
{
HtmlTextNode textNode = new HtmlTextNode();
textNode.Text = textToken.Text;
position++;
while (tokens.Count > position && (textToken = tokens[position] as HtmlTextToken) != null)
{
textNode.Text += textToken.Text;
position++;
}
parentNode.Children.Add(textNode);
}
else if (beginSpanToken != null)
{
HtmlSpanNode spanNode = new HtmlSpanNode();
position++;
GetAttributes(spanNode, beginSpanToken);
GetContents(spanNode, tokens, ref position);
if (tokens.Count < position || tokens[position] as HtmlEndSpanToken == null)
{
if (throwExceptions)
{
throw new Exception("Missing end span tag");
}
}
parentNode.Children.Add(spanNode);
position++;
}
else if (endSpanToken != null)
{
if (parentNode.GetType() == typeof(HtmlSpanNode))
{
return;
}
else
{
if (throwExceptions)
{
throw new Exception("Encountered closing span tag without matching open tag.");
}
else
{
position++;
}
}
}
else if (beginDivToken != null)
{
HtmlDivNode divNode = new HtmlDivNode();
position++;
GetAttributes(divNode, beginDivToken);
GetContents(divNode, tokens, ref position);
if (tokens.Count <= position || tokens[position] as HtmlEndDivToken == null)
{
if (throwExceptions)
{
throw new Exception("Missing end div tag");
}
}
parentNode.Children.Add(divNode);
position++;
}
else if (endDivToken != null)
{
if (parentNode.GetType() == typeof(HtmlDivNode))
{
return;
}
else
{
if (throwExceptions)
{
throw new Exception("Encountered closing div tag without matching open tag.");
}
else
{
position++;
}
}
}
else if (brToken != null)
{
HtmlBrNode brNode = new HtmlBrNode();
GetAttributes(brNode, brToken);
parentNode.Children.Add(brNode);
position++;
}
else if (imgToken != null)
{
HtmlImgNode imgNode = new HtmlImgNode();
GetAttributes(imgNode, imgToken);
parentNode.Children.Add(imgNode);
position++;
}
else
{
position++;
}
if (tokens.Count > position)
{
currentToken = tokens[position];
}
else
{
return;
}
}
}
private static void GetAttributes(HtmlNode htmlNode, HtmlToken htmlToken)
{
foreach (KeyValuePair<string, string> kvp in htmlToken.Attributes)
{
htmlNode.AddAttribute(kvp);
}
}
public static HtmlNode Parse(string text)
{
List<HtmlToken> tokens = Tokenize(text);
HtmlNode rootNode = Parse(tokens);
return rootNode;
//return Parse(Tokenize(text));
}
}
}

View File

@@ -0,0 +1,149 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<ProjectGuid>{A6FA0455-ACB5-4E80-9E58-6B79976AA717}</ProjectGuid>
<ProjectTypeGuids>{6D335F3A-9D43-41b4-9D22-F6F17C4BE596};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>PlanB.Html</RootNamespace>
<AssemblyName>Plan B Html Parser</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<XnaFrameworkVersion>v3.1</XnaFrameworkVersion>
<XnaPlatform>Windows</XnaPlatform>
<XnaCrossPlatformGroupID>1aed1ad2-9777-46c5-92fe-ef987622475f</XnaCrossPlatformGroupID>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<SccProjectName>SAK</SccProjectName>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\x86\Debug</OutputPath>
<DefineConstants>DEBUG;TRACE;WINDOWS</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
<UseVSHostingProcess>false</UseVSHostingProcess>
<PlatformTarget>x86</PlatformTarget>
<XnaCompressContent>false</XnaCompressContent>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\x86\Release</OutputPath>
<DefineConstants>TRACE;WINDOWS</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
<UseVSHostingProcess>false</UseVSHostingProcess>
<PlatformTarget>x86</PlatformTarget>
<XnaCompressContent>true</XnaCompressContent>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Xna.Framework, Version=3.1.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d, processorArchitecture=x86">
<Private>False</Private>
<SpecificVersion>True</SpecificVersion>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Game, Version=3.1.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d, processorArchitecture=MSIL">
<Private>False</Private>
<SpecificVersion>True</SpecificVersion>
</Reference>
<Reference Include="mscorlib">
<Private>False</Private>
</Reference>
<Reference Include="System">
<Private>False</Private>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml">
<Private>False</Private>
</Reference>
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
<Private>False</Private>
</Reference>
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Nodes\HtmlBrNode.cs" />
<Compile Include="Nodes\HtmlDivNode.cs" />
<Compile Include="Nodes\HtmlImgNode.cs" />
<Compile Include="Nodes\HtmlSpanNode.cs" />
<Compile Include="Parser.cs" />
<Compile Include="Nodes\HtmlDocumentNode.cs" />
<Compile Include="Nodes\HtmlNode.cs" />
<Compile Include="Nodes\HtmlTextNode.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Tokens\HtmlBeginDivToken.cs" />
<Compile Include="Tokens\HtmlBeginSpanToken.cs" />
<Compile Include="Tokens\HtmlBrToken.cs" />
<Compile Include="Tokens\HtmlEndDivToken.cs" />
<Compile Include="Tokens\HtmlEndSpanToken.cs" />
<Compile Include="Tokens\HtmlImgToken.cs" />
<Compile Include="Tokens\HtmlTextToken.cs" />
<Compile Include="Tokens\HtmlToken.cs" />
</ItemGroup>
<ItemGroup>
<NestedContentProject Include="Content\Content.contentproj">
<Project>730f03d9-cb96-43a9-88e3-a8687a66cf5e</Project>
<Visible>False</Visible>
</NestedContentProject>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
<Visible>False</Visible>
<ProductName>.NET Framework 2.0 %28x86%29</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
<Visible>False</Visible>
<ProductName>.NET Framework 3.0 %28x86%29</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Xna.Framework.3.1">
<Visible>False</Visible>
<ProductName>Microsoft XNA Framework Redistributable 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\Microsoft.Xna.GameStudio.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,10 @@
""
{
"FILE_VERSION" = "9237"
"ENLISTMENT_CHOICE" = "NEVER"
"PROJECT_FILE_RELATIVE_PATH" = ""
"NUMBER_OF_EXCLUDED_FILES" = "0"
"ORIGINAL_PROJECT_FILE_PATH" = ""
"NUMBER_OF_NESTED_PROJECTS" = "1"
"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
}

View File

@@ -0,0 +1,31 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Plan B Html Parser")]
[assembly: AssemblyProduct("Plan B Html Parser")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2009")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("b8545a1e-c024-4eec-9d5e-a3e470e43671")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.0.0.0")]

View File

@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PlanB.Html.Tokens
{
public class HtmlBeginDivToken:HtmlToken
{
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PlanB.Html.Tokens
{
public class HtmlBeginSpanToken: HtmlToken
{
public override string ToString()
{
return "<span>";
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PlanB.Html.Tokens
{
public class HtmlBrToken: HtmlToken
{
public override string ToString()
{
return "<br/>";
}
}
}

View File

@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PlanB.Html.Tokens
{
public class HtmlEndDivToken: HtmlToken
{
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PlanB.Html.Tokens
{
public class HtmlEndSpanToken: HtmlToken
{
public override string ToString()
{
return "</span>";
}
}
}

View File

@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PlanB.Html.Tokens
{
public class HtmlImgToken: HtmlToken
{
}
}

View File

@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PlanB.Html.Tokens
{
public class HtmlTextToken: HtmlToken
{
public string Text { get; set; }
public HtmlTextToken()
{
Text = String.Empty;
}
public HtmlTextToken(string str)
{
Text = str;
}
public override string ToString()
{
return Text ?? String.Empty;
}
}
}

View File

@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace PlanB.Html.Tokens
{
public class HtmlToken
{
public List<KeyValuePair<string, string>> Attributes { get; set; }
public HtmlToken()
{
Attributes = new List<KeyValuePair<string, string>>();
}
public override string ToString()
{
return String.Empty;
}
internal void AddAttributes(Match m)
{
Group attributeNameGroup = m.Groups["attributeName"];
Group attributeValueGroup = m.Groups["attributeValue"];
//int numAttributes = m.Groups["attributeName"].Captures.Count;
int numAttributes = attributeNameGroup.Captures.Count;
for (int i = 0; i < numAttributes; i++)
{
//KeyValuePair<string, string> attribute = new KeyValuePair<string, string>(m.Groups["attributeName"].Captures[i].ToString(), m.Groups["attributeValue"].Captures[i].ToString());
KeyValuePair<string, string> attribute = new KeyValuePair<string, string>(attributeNameGroup.Captures[i].ToString(), attributeValueGroup.Captures[i].ToString());
Attributes.Add(attribute);
}
}
}
}

View File

@@ -0,0 +1,136 @@
==========================================================================
Visual Studio Team System: Overview of Authoring and Running Tests
==========================================================================
This overview describes the features for authoring and running tests in
Visual Studio Team System and Visual Studio Team Edition for Software Testers.
Opening Tests
-------------
To open a test, open a test project or a test metadata file (a file with
extension .vsmdi) that contains the definition of the test. You can find
test projects and metadata files in Solution Explorer.
Viewing Tests
-------------
To see which tests are available to you, open the Test View window. Or,
if you have installed Team Edition for Software Testers, you can also open
the Test List Editor window to view tests.
To open the Test View window, click the Test menu, point to Windows, and
then click Test View. To open the Test List Editor window (if you have
installed Team Edition for Software Testers), click Test, point to Windows,
and then click Test List Editor.
Running Tests
-------------
You can run tests from the Test View window and the Test List Editor window.
See Viewing Tests to learn how to open these windows. To run one or more
tests displayed in the Test View window, first select the tests in that
window; to select multiple tests, hold either the Shift or CTRL key while
clicking tests. Then click the Run Tests button in the Test View window
toolbar.
If you have installed Visual Studio Team Edition for Software Testers, you can
also use the Test List Editor window to run tests. To run tests in Test List Editor,
select the check box next to each test that you want to run. Then click the
Run Tests button in the Test List Editor window toolbar.
Viewing Test Results
--------------------
When you run a test or a series of tests, the results of the test run will be
shown in the Test Results window. Each individual test in the run is shown on
a separate line so that you can see its status. The window contains an
embedded status bar in the top half of the window that provides you with
summary details of the complete test run.
To see more detailed results for a particular test result, double-click it in
the Test Results window. This opens a window that provides more information
about the particular test result, such as any specific error messages returned
by the test.
Changing the way that tests are run
-----------------------------------
Each time you run one or more tests, a collection of settings is used to
determine how those tests are run. These settings are contained in a “test
run configuration” file.
Here is a partial list of the changes you can make with a test run
configuration file:
- Change the naming scheme for each test run.
- Change the test controller that the tests are run on so that you can run
tests remotely.
- Gather code coverage data for the code being tested so that you can see
which lines of code are covered by your tests.
- Enable and disable test deployment.
- Specify additional files to deploy before tests are run.
- Select a different host, ASP.NET, for running ASP.NET unit tests.
- Select a different host, the smart device test host, for running smart device unit tests.
- Set various properties for the test agents that run your tests.
- Run custom scripts at the start and end of each test run so that you can
set up the test environment exactly as required each time tests are run.
- Set time limits for tests and test runs.
- Set the browser mix and the number of times to repeat Web tests in the
test run.
By default, a test run configuration file is created whenever you create a
new test project. You make changes to this file by double-clicking it in
Solution Explorer and then changing its settings. (Test run configuration
files have the extension .testrunconfig.)
A solution can contain multiple test run configuration files. Only one of
those files, known as the “Active” test run configuration file, is used to
determine the settings that are currently used for test runs. You select
the active test run configuration by clicking Select Active Test Run
Configuration on the Test menu.
-------------------------------------------------------------------------------
Test Types
----------
Using Visual Studio Team Edition for Software Testers, you can create a number
of different test types:
Unit test: Use a unit test to create a programmatic test in C++, Visual C# or
Visual Basic that exercises source code. A unit test calls the methods of a
class, passing suitable parameters, and verifies that the returned value is
what you expect.
There are three specialized variants of unit tests:
- Data-driven unit tests are created when you configure a unit test to be
called repeatedly for each row of a data source. The data from each row
is used by the unit test as input data.
- ASP.NET unit tests are unit tests that exercise code in an ASP.NET Web
application.
- Smart device unit tests are unit tests that are deployed to a smart device
or emulator and then executed by the smart device test host.
Web Test: Web tests consist of an ordered series of HTTP requests that you
record in a browser session using Microsoft Internet Explorer. You can have
the test report specific details about the pages or sites it requests, such
as whether a particular page contains a specified string.
Load Test: You use a load test to encapsulate non-manual tests, such as
unit, Web, and generic tests, and then run them simultaneously by using
virtual users. Running these tests under load generates test results,
including performance and other counters, in tables and in graphs.
Generic test: A generic test is an existing program wrapped to function as a
test in Visual Studio. The following are examples of tests or programs that
you can turn into generic tests:
- An existing test that uses process exit codes to communicate whether the
test passed or failed. 0 indicates passing and any other value indicates
a failure.
- A general program to obtain specific functionality during a test scenario.
- A test or program that uses a special XML file (called a “summary results
file”), to communicate detailed results.
Manual test: The manual test type is used when the test tasks are to be
completed by a test engineer as opposed to an automated script.
Ordered test: Use an ordered test to execute a set of tests in an order you
specify.
-------------------------------------------------------------------------------

View File

@@ -0,0 +1,178 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PlanB.Html.Nodes;
using PlanB.Html;
namespace TestProject1
{
[TestClass]
public class ParseErrorTests
{
public ParseErrorTests()
{
//
// TODO: Add constructor logic here
//
}
private TestContext testContextInstance;
/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test run.
///</summary>
public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}
#region Additional test attributes
//
// You can use the following additional attributes as you write your tests:
//
// Use ClassInitialize to run code before running the first test in the class
// [ClassInitialize()]
// public static void MyClassInitialize(TestContext testContext) { }
//
// Use ClassCleanup to run code after all tests in a class have run
// [ClassCleanup()]
// public static void MyClassCleanup() { }
//
// Use TestInitialize to run code before running each test
// [TestInitialize()]
// public void MyTestInitialize() { }
//
// Use TestCleanup to run code after each test has run
// [TestCleanup()]
// public void MyTestCleanup() { }
//
#endregion
[TestMethod]
public void Test_Parse_UnknownTag()
{
String htmlText = "<asdf></asdf>";
String expectedResult = "&lt;asdf&gt;&lt;/asdf&gt;";
HtmlNode htmlNode = Parser.Parse(htmlText);
Assert.IsNotNull(htmlNode, "The HtmlNode returned by the parser is null.");
Assert.AreEqual<int>(htmlNode.Children.Count, 1);
Assert.IsInstanceOfType(htmlNode.Children[0], typeof(HtmlTextNode));
Assert.AreEqual<int>(htmlNode.Children[0].Children.Count, 0);
Assert.AreEqual<string>(expectedResult, htmlNode.InnerHtml);
}
[TestMethod]
public void Test_Parse_UnclosedTag()
{
String htmlText = "<div>asdf<span>fdsa</span>jkl;";
String expectedResult = "<div>asdf<span>fdsa</span>jkl;</div>";
HtmlNode htmlNode = Parser.Parse(htmlText);
Assert.IsNotNull(htmlNode, "The HtmlNode returned by the parser is null.");
Assert.IsInstanceOfType(htmlNode.Children[0], typeof(HtmlDivNode));
Assert.AreEqual<string>(expectedResult, htmlNode.InnerHtml);
}
[TestMethod]
public void Test_Parse_UnescapedAmpersand()
{
String htmlText = "hello&world";
String expectedResult = "hello&amp;world";
HtmlNode htmlNode = Parser.Parse(htmlText);
Assert.IsNotNull(htmlNode);
Assert.AreEqual<string>(expectedResult, htmlNode.InnerHtml);
}
[TestMethod]
public void Test_Parse_UnescapedLessThan()
{
String htmlText = "hello<world";
String expectedResult = "hello&lt;world";
HtmlNode htmlNode = Parser.Parse(htmlText);
Assert.IsNotNull(htmlNode);
Assert.AreEqual<string>(expectedResult, htmlNode.InnerHtml);
}
[TestMethod]
public void Test_Parse_UnescapedLessThanThatLooksLikeATag()
{
String htmlText = "hello<div world";
String expectedResult = "hello&lt;div world";
HtmlNode htmlNode = Parser.Parse(htmlText);
Assert.IsNotNull(htmlNode);
Assert.AreEqual<string>(expectedResult, htmlNode.InnerHtml);
}
[TestMethod]
public void Test_Parse_UnescapedGreaterThan()
{
String htmlText = "hello>world";
String expectedResult = "hello&gt;world";
HtmlNode htmlNode = Parser.Parse(htmlText);
Assert.IsNotNull(htmlNode);
Assert.AreEqual<string>(expectedResult, htmlNode.InnerHtml);
}
[TestMethod]
public void Test_Parse_UnescapedQuote()
{
String htmlText = "hello\"world";
String expectedResult = "hello&quot;world";
HtmlNode htmlNode = Parser.Parse(htmlText);
Assert.IsNotNull(htmlNode);
Assert.IsInstanceOfType(htmlNode.Children[0], typeof(HtmlTextNode));
Assert.AreEqual<string>(expectedResult, htmlNode.InnerHtml);
}
[TestMethod]
public void Test_Parse_UnopenedTag()
{
String htmlText = "<div>hello world</span></div>";
String expectedResult = "<div>hello world</div>";
HtmlNode htmlNode = Parser.Parse(htmlText);
Assert.IsNotNull(htmlNode);
Assert.IsInstanceOfType(htmlNode.Children[0], typeof(HtmlDivNode));
Assert.AreEqual<string>(expectedResult, htmlNode.InnerHtml);
}
}
}

View File

@@ -0,0 +1,346 @@
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PlanB.Html.Nodes;
using PlanB.Html;
namespace TestProject1
{
/// <summary>
/// Summary description for UnitTest1
/// </summary>
[TestClass]
public class ParseTests
{
public ParseTests()
{
//
// TODO: Add constructor logic here
//
}
private TestContext testContextInstance;
/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test run.
///</summary>
public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}
#region Additional test attributes
//
// You can use the following additional attributes as you write your tests:
//
// Use ClassInitialize to run code before running the first test in the class
// [ClassInitialize()]
// public static void MyClassInitialize(TestContext testContext) { }
//
// Use ClassCleanup to run code after all tests in a class have run
// [ClassCleanup()]
// public static void MyClassCleanup() { }
//
// Use TestInitialize to run code before running each test
// [TestInitialize()]
// public void MyTestInitialize() { }
//
// Use TestCleanup to run code after each test has run
// [TestCleanup()]
// public void MyTestCleanup() { }
//
#endregion
[TestMethod]
public void Test_Parse_HtmlTextNode()
{
String htmlText = "asdf";
String expectedResult = "asdf";
HtmlNode htmlNode = Parser.Parse(htmlText);
Assert.IsNotNull(htmlNode, "The HtmlNode returned by the parser is null.");
Assert.AreEqual<int>(htmlNode.Children.Count, 1);
Assert.IsInstanceOfType(htmlNode.Children[0], typeof(HtmlTextNode));
HtmlTextNode htmlTextNode = htmlNode.Children[0] as HtmlTextNode;
Assert.AreEqual(expectedResult, htmlTextNode.Text);
}
[TestMethod]
public void Test_Parse_Returns_HtmlDocumentNode()
{
String htmlText = String.Empty;
HtmlNode htmlNode = Parser.Parse(htmlText);
Assert.IsInstanceOfType(htmlNode, typeof(HtmlDocumentNode));
}
[TestMethod]
public void Test_HtmlTextNode_Constructors()
{
HtmlTextNode htmlTextNode = new HtmlTextNode();
Assert.IsNotNull(htmlTextNode.Attributes, "The default constructor failed to initialize the Attributes property.");
Assert.IsNotNull(htmlTextNode.Children, "The default constructor failed to initialize the Children property.");
Assert.IsNotNull(htmlTextNode.InnerHtml, "The default constructor failed to initialize the InnerHtml property.");
Assert.IsNotNull(htmlTextNode.OuterHtml, "The default constructor failed to initialize the OuterHtml property.");
Assert.IsNotNull(htmlTextNode.Text, "The default constructor failed to initialize the Text property");
Assert.IsNotNull(htmlTextNode.Type, "The default constructor failed to initialize the Type property");
Assert.AreEqual<HtmlNodeType>(HtmlNodeType.Text_, htmlTextNode.Type);
String expectedValue = "This is some sample text.";
htmlTextNode = new HtmlTextNode(expectedValue);
Assert.IsNotNull(htmlTextNode.Attributes, "The HtmlTextNode(string) constructor failed to initialize the Attributes property.");
Assert.IsNotNull(htmlTextNode.Children, "The HtmlTextNode(string) constructor failed to initialize the Children property.");
Assert.IsNotNull(htmlTextNode.InnerHtml, "The HtmlTextNode(string) constructor failed to initialize the InnerHtml property.");
Assert.AreEqual<String>(String.Empty, htmlTextNode.InnerHtml);
Assert.IsNotNull(htmlTextNode.OuterHtml, "The HtmlTextNode(string) constructor failed to initialize the OuterHtml property.");
Assert.AreEqual<String>(expectedValue, htmlTextNode.OuterHtml);
Assert.IsNotNull(htmlTextNode.Text, "The HtmlTextNode(string) constructor failed to initialize the Text property");
Assert.AreEqual<String>(expectedValue, htmlTextNode.Text);
Assert.IsNotNull(htmlTextNode.Type, "The HtmlTextNode(string) constructor failed to initialize the Type property");
Assert.AreEqual<HtmlNodeType>(HtmlNodeType.Text_, htmlTextNode.Type);
}
[TestMethod]
public void Test_HtmlDocumentNode_Constructors()
{
HtmlDocumentNode htmlDocumentNode = new HtmlDocumentNode();
Assert.IsNotNull(htmlDocumentNode.Attributes);
Assert.IsNotNull(htmlDocumentNode.Children);
Assert.AreEqual<int>(0, htmlDocumentNode.Children.Count);
Assert.IsNotNull(htmlDocumentNode.InnerHtml);
Assert.AreEqual<String>(String.Empty, htmlDocumentNode.InnerHtml);
Assert.IsNotNull(htmlDocumentNode.OuterHtml);
Assert.AreEqual<String>(String.Empty, htmlDocumentNode.OuterHtml);
Assert.IsNotNull(htmlDocumentNode.Type);
Assert.AreEqual<HtmlNodeType>(HtmlNodeType.Document_, htmlDocumentNode.Type);
}
[TestMethod]
public void Test_HtmlBrNode_Constructor()
{
HtmlBrNode htmlBrNode = new HtmlBrNode();
String expectedOuterHtml = "<br />";
Assert.IsNotNull(htmlBrNode.Attributes, "The default constructor failed to initialize the Attributes property.");
Assert.AreEqual<int>(0, htmlBrNode.Attributes.Count);
Assert.IsNotNull(htmlBrNode.Children, "The default constructor failed to initialize the Children property.");
Assert.AreEqual<int>(0, htmlBrNode.Children.Count);
Assert.IsNotNull(htmlBrNode.InnerHtml, "The default constructor failed to initialize the InnerHtml property.");
Assert.AreEqual<String>(htmlBrNode.InnerHtml, String.Empty);
Assert.IsNotNull(htmlBrNode.OuterHtml, "The default constructor failed to initialize the OuterHtml property.");
Assert.AreEqual<String>(htmlBrNode.OuterHtml, expectedOuterHtml);
Assert.IsNotNull(htmlBrNode.Type, "The default constructor failed to initialize the Type property");
Assert.AreEqual<HtmlNodeType>(HtmlNodeType.Br, htmlBrNode.Type);
}
[TestMethod]
public void Test_HtmlSpanNode_Constructor()
{
//Default constructor
HtmlSpanNode htmlSpanNode = new HtmlSpanNode();
Assert.IsNotNull(htmlSpanNode.Attributes, "The default constructor failed to initialize the Attributes property.");
Assert.AreEqual<int>(0, htmlSpanNode.Attributes.Count);
Assert.IsNotNull(htmlSpanNode.Children, "The default constructor failed to initialize the Children property.");
Assert.AreEqual<int>(0, htmlSpanNode.Children.Count);
Assert.IsNotNull(htmlSpanNode.InnerHtml, "The default constructor failed to initialize the InnerHtml property.");
Assert.AreEqual<string>(String.Empty, htmlSpanNode.InnerHtml);
Assert.IsNotNull(htmlSpanNode.OuterHtml, "The default constructor failed to initialize the OuterHtml property.");
Assert.AreEqual<string>("<span />", htmlSpanNode.OuterHtml);
Assert.IsNotNull(htmlSpanNode.Type, "The default constructor failed to initialize the Type property");
Assert.AreEqual<HtmlNodeType>(HtmlNodeType.Span, htmlSpanNode.Type);
//HtmlSpanNode(String)
String text = "test";
htmlSpanNode = new HtmlSpanNode(text);
Assert.IsNotNull(htmlSpanNode.Attributes, "The HtmlSpanNode(String) constructor failed to initialize the Attributes property.");
Assert.AreEqual<int>(0, htmlSpanNode.Attributes.Count);
Assert.IsNotNull(htmlSpanNode.Children, "The HtmlSpanNode(String) constructor failed to initialize the Children property.");
Assert.AreEqual<int>(1, htmlSpanNode.Children.Count);
Assert.IsNotNull(htmlSpanNode.InnerHtml, "The HtmlSpanNode(String) constructor failed to initialize the InnerHtml property.");
Assert.AreEqual<string>(text, htmlSpanNode.InnerHtml);
Assert.IsNotNull(htmlSpanNode.OuterHtml, "The HtmlSpanNode(String) constructor failed to initialize the OuterHtml property.");
Assert.AreEqual<string>("<span>" + text + "</span>", htmlSpanNode.OuterHtml);
Assert.IsNotNull(htmlSpanNode.Type, "The HtmlSpanNode(String) constructor failed to initialize the Type property");
Assert.AreEqual<HtmlNodeType>(HtmlNodeType.Span, htmlSpanNode.Type);
//HtmlSpanNode(IEnumerable<HtmlNode>)
htmlSpanNode = new HtmlSpanNode(new HtmlNode[] { new HtmlTextNode(text), new HtmlBrNode(), new HtmlTextNode(text) });
Assert.IsNotNull(htmlSpanNode.Attributes, "The HtmlSpanNode(IEnumerable<HtmlNode>) constructor failed to initialize the Attributes property.");
Assert.AreEqual<int>(0, htmlSpanNode.Attributes.Count);
Assert.IsNotNull(htmlSpanNode.Children, "The HtmlSpanNode(IEnumerable<HtmlNode>) constructor failed to initialize the Children property.");
Assert.AreEqual<int>(3, htmlSpanNode.Children.Count);
Assert.IsNotNull(htmlSpanNode.InnerHtml, "The HtmlSpanNode(IEnumerable<HtmlNode>) constructor failed to initialize the InnerHtml property.");
Assert.AreEqual<string>(text + "<br />" + text, htmlSpanNode.InnerHtml);
Assert.IsNotNull(htmlSpanNode.OuterHtml, "The HtmlSpanNode(IEnumerable<HtmlNode>) constructor failed to initialize the OuterHtml property.");
Assert.AreEqual<string>("<span>" + text + "<br />" + text + "</span>", htmlSpanNode.OuterHtml);
Assert.IsNotNull(htmlSpanNode.Type, "The HtmlSpanNode(IEnumerable<HtmlNode>) constructor failed to initialize the Type property");
Assert.AreEqual<HtmlNodeType>(HtmlNodeType.Span, htmlSpanNode.Type);
}
[TestMethod]
public void Test_Parse_TextWithSpanTag()
{
String htmlText = "asdf<span>123</span>fdsa";
String expectedFirstNodeOuterHtml = "asdf";
String expectedSecondNodeOuterHtml = "<span>123</span>";
String expectedThirdNodeOuterHtml = "fdsa";
String expectedSecondNodeInnerHtml = "123";
HtmlNode htmlNode = Parser.Parse(htmlText);
Assert.IsNotNull(htmlNode, "");
Assert.IsInstanceOfType(htmlNode, typeof(HtmlDocumentNode));
Assert.AreEqual<string>(htmlText, htmlNode.OuterHtml);
Assert.AreEqual<int>(3, htmlNode.Children.Count);
Assert.IsInstanceOfType(htmlNode.Children[0], typeof(HtmlTextNode));
Assert.AreEqual<string>(expectedFirstNodeOuterHtml, htmlNode.Children[0].OuterHtml);
Assert.AreEqual<int>(0, htmlNode.Children[0].Children.Count);
Assert.IsInstanceOfType(htmlNode.Children[1], typeof(HtmlSpanNode));
Assert.AreEqual<string>(expectedSecondNodeOuterHtml, htmlNode.Children[1].OuterHtml);
Assert.AreEqual<int>(1, htmlNode.Children[1].Children.Count);
Assert.IsInstanceOfType(htmlNode.Children[1].Children[0], typeof(HtmlTextNode));
Assert.AreEqual<string>(expectedSecondNodeInnerHtml, htmlNode.Children[1].Children[0].OuterHtml);
Assert.AreEqual<int>(0, htmlNode.Children[1].Children[0].Children.Count);
Assert.IsInstanceOfType(htmlNode.Children[2], typeof(HtmlTextNode));
Assert.AreEqual<string>(expectedThirdNodeOuterHtml, htmlNode.Children[2].OuterHtml);
Assert.AreEqual<int>(0, htmlNode.Children[2].Children.Count);
}
[TestMethod]
public void Test_Parse_TextWithBrTag()
{
String htmlText = "asdf<br />asdf";
String expectedResult = "asdf<br />asdf";
HtmlNode htmlNode = Parser.Parse(htmlText);
Assert.IsNotNull(htmlNode, "The HtmlNode returned by the parser is null.");
Assert.AreEqual<int>(htmlNode.Children.Count, 3);
Assert.IsInstanceOfType(htmlNode.Children[0], typeof(HtmlTextNode));
HtmlTextNode htmlTextNode = htmlNode.Children[0] as HtmlTextNode;
Assert.IsInstanceOfType(htmlNode.Children[1], typeof(HtmlBrNode));
HtmlBrNode htmlBrNode = htmlNode.Children[1] as HtmlBrNode;
Assert.IsInstanceOfType(htmlNode.Children[2], typeof(HtmlTextNode));
htmlTextNode = htmlNode.Children[2] as HtmlTextNode;
Assert.AreEqual(expectedResult, htmlNode.InnerHtml);
}
[TestMethod]
public void Test_Parse_SpanWithStyle()
{
String htmlText = "<span style=\"color:black\">asdf</span>";
String expectedResult = "<span style=\"color:black;\">asdf</span>";
HtmlNode htmlNode = Parser.Parse(htmlText);
Assert.IsNotNull(htmlNode, "The HtmlNode returned by the parser is null.");
Assert.AreEqual<int>(htmlNode.Children.Count, 1);
Assert.IsInstanceOfType(htmlNode.Children[0], typeof(HtmlSpanNode));
HtmlSpanNode spanNode = htmlNode.Children[0] as HtmlSpanNode;
IEnumerable<KeyValuePair<string,string>> spanStyleAttributes = spanNode.Attributes.Where(i=>i.Key == "style");
/*
Assert.AreEqual<int>(spanStyleAttributes.Count(), 1);
KeyValuePair<string, string> spanStyleAttribute = spanStyleAttributes.First();
Assert.AreEqual<string>(spanStyleAttribute.Value, "color:black");
/**/
IEnumerable<KeyValuePair<string, string>> spanColorStyles = spanNode.Styles.Where(i => i.Key == "color");
Assert.AreEqual<int>(spanColorStyles.Count(), 1);
KeyValuePair<string, string> spanColorStyle = spanColorStyles.First();
//Assert.AreEqual<string>(spanColorStyle.Value, "rgb(0,0,0)");
Assert.AreEqual<string>(spanColorStyle.Value, "black");
/**/
Assert.AreEqual(expectedResult, htmlNode.InnerHtml);
}
[TestMethod]
public void Test_Parse_Div()
{
String htmlText = "<div>asdf</div>";
String expectedResult = "<div>asdf</div>";
HtmlNode htmlNode = Parser.Parse(htmlText);
Assert.IsNotNull(htmlNode, "The HtmlNode returned by the parser is null.");
Assert.AreEqual<int>(htmlNode.Children.Count, 1);
Assert.IsInstanceOfType(htmlNode.Children[0], typeof(HtmlDivNode));
HtmlDivNode divNode = htmlNode.Children[0] as HtmlDivNode;
Assert.AreEqual<int>(divNode.Children.Count, 1);
Assert.AreEqual<string>(expectedResult, htmlNode.InnerHtml);
}
[TestMethod]
public void Test_Parse_Img()
{
String htmlText = "<img src=\"http://blogs.msdn.com/blogfiles/klevereblog/WindowsLiveWriter/Bingishere_A002/bing-logo_2.jpg\"/>";
String expectedResult = "<img src=\"http://blogs.msdn.com/blogfiles/klevereblog/WindowsLiveWriter/Bingishere_A002/bing-logo_2.jpg\" />";
HtmlNode htmlNode = Parser.Parse(htmlText);
Assert.IsNotNull(htmlNode, "The HtmlNode returned by the parser is null.");
Assert.AreEqual<int>(htmlNode.Children.Count, 1);
Assert.IsInstanceOfType(htmlNode.Children[0], typeof(HtmlImgNode));
HtmlImgNode imgNode = htmlNode.Children[0] as HtmlImgNode;
Assert.AreEqual<int>(imgNode.Children.Count, 0);
Assert.AreEqual<string>(expectedResult, htmlNode.InnerHtml);
Assert.AreEqual<int>(imgNode.Attributes.Count, 1);
Assert.AreEqual<int>(imgNode.Styles.Count, 0);
var temp = imgNode.Attributes.Where(i=>i.Key == "src");
Assert.AreEqual<int>(temp.Count(), 1);
Assert.AreEqual<string>(temp.Single().Value, "http://blogs.msdn.com/blogfiles/klevereblog/WindowsLiveWriter/Bingishere_A002/bing-logo_2.jpg");
}
}
}

View File

@@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("TestProject1")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("TestProject1")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2009")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM componenets. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("e044337f-2da1-429d-8f24-45bc7651026c")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,68 @@
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{9E7D5692-C2E9-4219-977E-143CC75B5737}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>TestProject1</RootNamespace>
<AssemblyName>TestProject1</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<SccProjectName>SAK</SccProjectName>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ParseErrorTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ParseTests.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="AuthoringTests.txt" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Plan B Html Parser\Plan B Html Parser.csproj">
<Project>{A6FA0455-ACB5-4E80-9E58-6B79976AA717}</Project>
<Name>Plan B Html Parser</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,10 @@
""
{
"FILE_VERSION" = "9237"
"ENLISTMENT_CHOICE" = "NEVER"
"PROJECT_FILE_RELATIVE_PATH" = ""
"NUMBER_OF_EXCLUDED_FILES" = "0"
"ORIGINAL_PROJECT_FILE_PATH" = ""
"NUMBER_OF_NESTED_PROJECTS" = "0"
"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
}