|
using System;
using System.Xml;
namespace XPathXmlStore
{
/// <summary>
/// Reads & writes data in xml file with XPath that doesn't exists yet.
/// </summary>
public class XPathStore
{
protected System.Xml.XmlDocument doc;
protected string sXmlFileName;
public XPathStore()
{
doc = new XmlDocument();
sXmlFileName = "..\\..\\settings.xml";
LoadSettings();
}
public void LoadSettings()
{
bool bReadOK = false;
try
{
// load the XML from file
doc.Load(sXmlFileName);
Console.WriteLine ("\nSETTINGS RELOADED" );
bReadOK = true;
}
catch (Exception e)
{
Console.WriteLine ("Exception: {0}", e.ToString());
}
if(!bReadOK)
{
doc.CreateComment("<?xml version=\"1.0\" ?>");
Console.WriteLine ("\nCREATED NEW" );
}
}
public void SaveSettings()
{
try{ doc.Save(sXmlFileName);
Console.WriteLine ("SETTINGS SAVED");}
catch (Exception e) { Console.WriteLine ("Exception: {0}", e.ToString()); }
}
/// <summary>
/// Get a xml node from xPath, if it doesn,t exists create it.
///
/// __________ EXAMPLES ____________
/// FdisSettings/User[@Name="FDIS_DTO"]/@AutoHide
/// FdisSettings/User[@Name="FDIS_DTO"]/ReportFilter/Report[@Name="Afvoermeldingen per Categorie"]/@ReloadThisSettings
/// </summary>
/// <param name="sXPath"></param>
/// <returns></returns>
public System.Xml.XmlNode QueryCreatNode( string sXPath )
{
Console.WriteLine ("Query xml document with Xpath={0}", sXPath );
XmlNode node = null;
try
{
XmlNodeList list = doc.SelectNodes( sXPath );
if( list.Count==1 )
return list.Item(0); // The easy way (The node exists)
else if( list.Count==0 )
{
Console.WriteLine (" ACTION) create XPath to node");
// Parses XPath in separate parts.
bool bParsingRandomText = false;
int nXpathPartStart = -1;
for( int i=0; i<sXPath.Length; i++ )
{
if( !bParsingRandomText &&
( (sXPath[i]=='/' || sXPath[i]=='\0') || i==sXPath.Length-1 ) &&
nXpathPartStart!=-1 )
{
if( i==sXPath.Length-1 )
i++; // Include last caracter
// handle this XPath part
node = QueryCreateNode( node, sXPath.Substring( nXpathPartStart, i-nXpathPartStart ) );
nXpathPartStart = -1;
}
else if( sXPath[i]=='\"' )
bParsingRandomText = !bParsingRandomText; // After '"' every character is possible, even '/'
else if( nXpathPartStart==-1 )
nXpathPartStart = i;
}
}
else
{
// ERROR (only one node expected)
Console.WriteLine ("ERROR Xpath:{0} returns {1} nodes\n Change XPath or XML so it returns ony one node", sXPath, list.Count );
}
}
catch(Exception e)
{
Console.WriteLine ("Exception: {0}", e.ToString());
return null;
}
return node;
}
// Create the required node for XPath
protected System.Xml.XmlNode QueryCreateNode( System.Xml.XmlNode node, string sXPathPart )
{
if( node==null )
node = doc;
Console.WriteLine (" HANDLE XPathPart) current node={0} XPath={1}", node.Name, sXPathPart );
//------------------------------------------------------------------------------------
// Step 1) Handle select part
int nNodeStart = -1;
int nAttrStart = -1;
int nLoc = 0;
for( ; nLoc<sXPathPart.Length; nLoc++ )
{
if( nAttrStart==-1 && nNodeStart==-1 )
{
if(sXPathPart[nLoc]=='@')
nAttrStart = nLoc+1;
else
nNodeStart = nLoc;
}
if( sXPathPart[nLoc]=='[' || nLoc==sXPathPart.Length-1 )
break;
}
if( nLoc==sXPathPart.Length-1 )
nLoc++; // Include last caracter
if( nNodeStart!=-1 )
{
Console.WriteLine (" ACTION) query node={0} with XPath={1}", sXPathPart.Substring(nNodeStart,nLoc-nNodeStart), sXPathPart) ;
// Query child Node
XmlNodeList NodeList = node.SelectNodes( sXPathPart );
if( NodeList.Count==1 )
return NodeList.Item(0);
else if( NodeList.Count==0 )
{
Console.WriteLine (" ACTION) create node={0}", sXPathPart.Substring(nNodeStart,nLoc-nNodeStart) );
node = node.AppendChild( doc.CreateElement( sXPathPart.Substring(nNodeStart,nLoc-nNodeStart) ) );
}
else
Console.WriteLine ("ERROR XpathPart:{0} returns {1} nodes\n Change XPath or XML so it returns ony one node", sXPathPart, NodeList.Count );
}
else if( nAttrStart!=-1 )
{
// Get Attribute
Console.WriteLine (" ACTION) Query node={0} for Attribute={1}", node.Name, sXPathPart.Substring(nAttrStart,nLoc-nAttrStart) );
XmlAttributeCollection AttrCol = node.Attributes;
node = AttrCol.GetNamedItem( sXPathPart.Substring(nAttrStart,nLoc-nAttrStart) );
if( node==null )
{
Console.WriteLine (" ACTION) create attibute={0}", sXPathPart.Substring(nAttrStart,nLoc-nAttrStart) );
node = AttrCol.SetNamedItem( doc.CreateAttribute( sXPathPart.Substring(nAttrStart,nLoc-nAttrStart) ) );
}
}
//------------------------------------------------------------------------------------
// Step 2) Handle filter parts
int nAttrNameStart = -1;
int nAttrTextStart = -1;
for( ; nLoc<sXPathPart.Length; nLoc++ )
{
if( sXPathPart[nLoc]=='@' )
nAttrNameStart = nLoc+1;
else if( sXPathPart[nLoc]=='\"' )
{
if( nAttrTextStart==-1 )
nAttrTextStart = nLoc+1;
else
{
Console.WriteLine (" ACTION) query node={0} for attribute={1}", node.Name, sXPathPart.Substring(nAttrNameStart, nAttrTextStart-nAttrNameStart-2 ) );
XmlNode attrNode = node.Attributes.GetNamedItem( sXPathPart.Substring(nAttrNameStart, nLoc-nAttrNameStart) );
if( attrNode==null )
{
Console.WriteLine (" ACTION) create attibute={0}", sXPathPart.Substring(nAttrNameStart, nAttrTextStart-nAttrNameStart-2) );
attrNode = doc.CreateAttribute( sXPathPart.Substring(nAttrNameStart, nAttrTextStart-nAttrNameStart-2) );
attrNode.Value = sXPathPart.Substring(nAttrTextStart, nLoc-nAttrTextStart);
node.Attributes.SetNamedItem( attrNode );
}
nAttrNameStart = -1;
nAttrTextStart = -1;
}
}
else if( sXPathPart[nLoc]==']' )
break;
}
return node;
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.