using System;
using System.Collections;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.XPath;
namespace WhidbeyProjectConverter
{
public class Converter
{
private XPathDocument document;
private ArrayList detectedNamespaces;
private XmlNamespaceManager namespaceManager;
private StringBuilder nmakeFiles = new StringBuilder();
private XmlDocument _whidbeyDoc = new XmlDocument();
private XmlDocument _everettDoc = new XmlDocument();
private XmlElement _everettBuildSettings;
private Regex _regEx = new Regex(@"'\$\(Configuration\)(\|\$\(Platform\)*)' == '(?<config>[a-zA-Z]+)(\|[a-zA-Z]+)'");
public Converter(string xmlSourceFile)
{
_whidbeyDoc.Load(xmlSourceFile);
_everettDoc.LoadXml("<VisualStudioProject><CSHARP><Build><Settings/><References/></Build><Files/></CSHARP></VisualStudioProject>");
_everettBuildSettings = (XmlElement)_everettDoc.SelectSingleNode("/VisualStudioProject/CSHARP/Build/Settings");
//Instantiate XPathDocument and load XML document
document = new XPathDocument(xmlSourceFile);
}
public string Convert()
{
// Create the namespaces in the whidbey xml project file.
CreateNamespaces();
foreach (string ns in detectedNamespaces)
{
int tokenPos = ns.IndexOf(':');
string prefix = ns.Substring(0, tokenPos);
string uri = ns.Substring(tokenPos + 1);
CreateCSharpNode(prefix, uri);
CreateBuildSettings(prefix, uri);
CreateReferences(prefix, uri);
CreateFiles(prefix, uri);
}
return _everettDoc.OuterXml;
}
public string GetProjectFiles()
{
// Create the namespaces in the whidbey xml project file.
CreateNamespaces();
foreach (string ns in detectedNamespaces)
{
int tokenPos = ns.IndexOf(':');
string prefix = ns.Substring(0, tokenPos);
string uri = ns.Substring(tokenPos + 1);
NmakeFileList(prefix, uri);
}
return nmakeFiles.ToString();
}
public void CreateNamespaces()
{
detectedNamespaces = new ArrayList();
XmlNode xmlNode = _whidbeyDoc.DocumentElement;
NamespaceDiscover(xmlNode);
//Create a namespace manager
namespaceManager = new XmlNamespaceManager(new NameTable());
foreach (string ns in detectedNamespaces)
{
int tokenPos = ns.IndexOf(':');
string prefix = ns.Substring(0, tokenPos);
string uri = ns.Substring(tokenPos + 1);
namespaceManager.AddNamespace(prefix.Trim(), uri.Trim());
}
}
private void NamespaceDiscover(XmlNode xNode)
{
string nsPrefix;
string nsUri;
namespaceManager = new XmlNamespaceManager(new NameTable());
if (xNode.NodeType == XmlNodeType.Element)
{
if (xNode.Attributes.Count > 0)
{
int attrNum = 0;
while (attrNum < xNode.Attributes.Count)
{
if (xNode.Attributes[attrNum].Name.StartsWith("xmlns"))
{
string nsDef = xNode.Attributes[attrNum].Name.Split('=')[0];
if (nsDef != "xmlns")
{
nsPrefix = nsDef.Split(':')[1];
}
else
{
nsPrefix = "def";
}
nsUri = xNode.Attributes[attrNum].Value;
detectedNamespaces.Add(string.Format("{0}: {1}", nsPrefix, nsUri));
}
attrNum++;
}
}
if (xNode.HasChildNodes)
{
int elemNum = 0;
while (elemNum < xNode.ChildNodes.Count)
{
NamespaceDiscover(xNode.ChildNodes[elemNum]);
elemNum++;
}
}
}
}
private void CreateCSharpNode(string prefix, string uri)
{
XmlElement csharpNode = (XmlElement)_everettDoc.SelectSingleNode("/VisualStudioProject/CSHARP");
//XmlAttribute projectTypeAtt = (XmlAttribute)_whidbeyDoc.SelectSingleNode("/Project/PropertyGroup/Property/@ProjectType");
XPathNodeIterator nodeIterator;
//Instantiate XPathNavigator
XPathNavigator navigator = document.CreateNavigator(); ;
string xpathQuery = prefix + ":Project/" + prefix + ":PropertyGroup/" + prefix + ":ProjectType";
//Instantiate XPathExpression
XPathExpression expression = navigator.Compile(xpathQuery);
if (namespaceManager != null)
expression.SetContext(namespaceManager);
//Execute XPath query
nodeIterator = navigator.Select(expression);
if (nodeIterator.MoveNext())
{
//Get the current node as XPathNavigator object
navigator = nodeIterator.Current;
csharpNode.SetAttribute("ProjectType", navigator.Value);
}
else
{
csharpNode.SetAttribute("ProjectType", "Local" );
}
//csharpNode.SetAttribute("ProjectType", navigator == null ? "Local" : navigator.Value);
csharpNode.SetAttribute("ProductVersion", "7.10.3077");
csharpNode.SetAttribute("SchemaVersion", "2");
// Get the project guid
xpathQuery = prefix + ":Project/" + prefix + ":PropertyGroup/" + prefix + ":ProjectGuid";
navigator = document.CreateNavigator();
//Instantiate XPathExpression
expression = navigator.Compile(xpathQuery);
if (namespaceManager != null)
expression.SetContext(namespaceManager);
//Execute XPath query
nodeIterator = navigator.Select(expression);
if (nodeIterator.MoveNext())
{
//Get the current node as XPathNavigator object
navigator = nodeIterator.Current;
csharpNode.SetAttribute("ProjectGuid", navigator.Value);
}
else
{
csharpNode.SetAttribute("ProjectGuid", Guid.NewGuid().ToString());
}
}
private void CreateBuildSettings(string prefix, string uri)
{
XPathNodeIterator nodeIterator;
//Instantiate XPathNavigator
XPathNavigator navigator = document.CreateNavigator();
string xpathQuery = prefix + ":Project/" + prefix + ":PropertyGroup";
//Instantiate XPathExpression
XPathExpression expression = navigator.Compile(xpathQuery);
if (namespaceManager != null)
expression.SetContext(namespaceManager);
//Execute XPath query
nodeIterator = navigator.Select(expression);
//Iterate through the resultant node set
while (nodeIterator.MoveNext())
{
//Get the current node as XPathNavigator object
navigator = nodeIterator.Current;
XmlElement configNode;
string condition = navigator.GetAttribute("Condition", "");
if (condition == "")
{
configNode = _everettBuildSettings;
// //Iterate through attributes if any
if (navigator.MoveToFirstChild())
{
do
{
configNode.SetAttribute(navigator.Name, navigator.Value);
}
while (navigator.MoveToNext());
navigator.MoveToParent();
}
}
else
{
configNode = GetEverettBuildConfiguration(condition.Trim());
if (navigator.MoveToFirstChild())
{
do
{
configNode.SetAttribute(navigator.Name, navigator.Value);
}
while (navigator.MoveToNext());
navigator.MoveToParent();
}
}
//Iterate through attributes if any
// if (navigator.MoveToFirstAttribute())
// {
// do
// {
// configNode.SetAttribute(navigator.Name, navigator.Value);
// }
// while (navigator.MoveToNextAttribute());
// navigator.MoveToParent();
// }
// //Iterate through attributes if any
if (navigator.HasAttributes)
{
while (navigator.MoveToNextAttribute())
configNode.SetAttribute(navigator.Name, navigator.Value);
// Return to the 'Parent' node of the attributes
navigator.MoveToParent();
}
}
}
private void CreateReferences(string prefix, string uri)
{
XmlElement everettReferencesRoot = (XmlElement)_everettDoc.SelectSingleNode("/VisualStudioProject/CSHARP/Build/References");
XPathNodeIterator nodeIterator;
//Instantiate XPathNavigator
XPathNavigator navigator = document.CreateNavigator();
string xpathQuery = prefix + ":Project/" + prefix + ":ItemGroup/" + prefix + ":Reference";
//Instantiate XPathExpression
XPathExpression expression = navigator.Compile(xpathQuery);
if (namespaceManager != null)
expression.SetContext(namespaceManager);
//Execute XPath query
nodeIterator = navigator.Select(expression);
//Iterate through the resultant node set
while (nodeIterator.MoveNext())
{
//Get the current node as XPathNavigator object
navigator = nodeIterator.Current;
XmlElement everettReferenceNode = _everettDoc.CreateElement("Reference");
if(navigator.MoveToAttribute("Include", ""))
{
everettReferenceNode.SetAttribute("Name", navigator.Value);
everettReferenceNode.SetAttribute("AssemblyName", navigator.Value);
navigator.MoveToParent();
}
if (navigator.MoveToAttribute("HintPath", ""))
{
everettReferenceNode.SetAttribute("HintPath", navigator.Value);
navigator.MoveToParent();
}
everettReferencesRoot.AppendChild(everettReferenceNode);
}
}
private void NmakeFileList(string prefix, string uri)
{
XPathNodeIterator nodeIterator;
//Instantiate XPathNavigator
XPathNavigator navigator = document.CreateNavigator();
XmlElement everettFilesRoot = (XmlElement)_everettDoc.SelectSingleNode("/VisualStudioProject/CSHARP/Files");
XmlElement everettIncludeRoot = _everettDoc.CreateElement("Include");
everettFilesRoot.AppendChild(everettIncludeRoot);
string[] xmlElements = { "Compile", "Content", "EmbeddedResource", "None" };
for (int i = 0; i < xmlElements.Length; i++)
{
string xpathQuery = prefix + ":Project/" + prefix + ":ItemGroup/" + prefix + ":" + xmlElements[i];
//Instantiate XPathExpression
XPathExpression expression = navigator.Compile(xpathQuery);
if (namespaceManager != null)
expression.SetContext(namespaceManager);
//Execute XPath query
nodeIterator = navigator.Select(expression);
//Iterate through the resultant node set
while (nodeIterator.MoveNext())
{
//Get the current node as XPathNavigator object
navigator = nodeIterator.Current;
if (navigator.MoveToAttribute("Include", ""))
{
nmakeFiles.Append(navigator.Value + " ");
navigator.MoveToParent();
}
}
}
}
private void CreateFiles(string prefix, string uri)
{
XmlElement everettFilesRoot = (XmlElement)_everettDoc.SelectSingleNode("/VisualStudioProject/CSHARP/Files");
XmlElement everettIncludeRoot = _everettDoc.CreateElement("Include");
everettFilesRoot.AppendChild(everettIncludeRoot);
XPathNodeIterator nodeIterator;
//Instantiate XPathNavigator
XPathNavigator navigator = document.CreateNavigator();
string[] xmlElements = {"Compile", "Content", "EmbeddedResource", "None"};
for (int i = 0; i < xmlElements.Length; i++)
{
string xpathQuery = prefix + ":Project/" + prefix + ":ItemGroup/" + prefix + ":" + xmlElements[i];
//Instantiate XPathExpression
XPathExpression expression = navigator.Compile(xpathQuery);
if (namespaceManager != null)
expression.SetContext(namespaceManager);
//Execute XPath query
nodeIterator = navigator.Select(expression);
//Iterate through the resultant node set
while (nodeIterator.MoveNext())
{
//Get the current node as XPathNavigator object
navigator = nodeIterator.Current;
XmlElement everettFileNode = _everettDoc.CreateElement("File");
if (navigator.MoveToAttribute("Include", ""))
{
everettFileNode.SetAttribute("RelPath", navigator.Value);
navigator.MoveToParent();
}
else
{
everettFileNode.SetAttribute("RelPath", "");
}
if (navigator.MoveToAttribute("Type", ""))
{
everettFileNode.SetAttribute("BuildAction", navigator.Value);
navigator.MoveToParent();
}
else
{
everettFileNode.SetAttribute("BuildAction", xmlElements[i]);
}
if (navigator.MoveToAttribute("SubType", ""))
{
everettFileNode.SetAttribute("SubType", navigator.Value);
navigator.MoveToParent();
}
if (navigator.MoveToAttribute("DependentUpon", ""))
{
everettFileNode.SetAttribute("DependentUpon", navigator.Value);
navigator.MoveToParent();
}
everettIncludeRoot.AppendChild(everettFileNode);
}
}
}
private XmlElement GetEverettBuildConfiguration(string condition)
{
Match m = _regEx.Match(condition);
string configName = m.Groups["config"].Value;
XmlElement configNode = (XmlElement)_everettBuildSettings.SelectSingleNode(string.Format("Config[@Name = '{0}']", configName));
if (configNode == null)
{
configNode = _everettDoc.CreateElement("Config");
configNode.SetAttribute("Name", configName);
_everettBuildSettings.AppendChild(configNode);
}
return configNode;
}
}
}