XML-Based Applications: |
|
The inventory of our store is created by adding store items to an XML file. To do this, once again, we take advantage of the XmlDocument, the XmlNode, and its derived classes. This inventory is created using the New Part form. We need to apply some rules in order to create a store item. Early rules can make the application easier to use and maintain. For example, we must create an item only if it can be clearly identified. This makes it easy to locate it when processing an order. We explain through the comments in the code. |
Practical Learning: Creating the Inventory |
System::Void btnNewMake_Click(System::Object * sender, System::EventArgs * e) { // The new car make will come from the New Make dialog box NewMake *frmMake = new NewMake; // Display the New Make dialog box and find out if the user clicked OK if( frmMake->ShowDialog() == DialogResult::OK ) { String *strNewMake = frmMake->txtNewMake->Text; // If the user didn't create a new Make, don't do anything if( strNewMake->Equals(S"") ) return; // Before adding the new make, check that it doesn't exist already if( this->cboMakes->FindStringExact(strNewMake) > 0 ) return; // Now you can add it this->cboMakes->Items->Add(strNewMake); // The user likely wants this new item selected this->cboMakes->Text = strNewMake; // Open the Cars.xml file XmlDocument *docXMLFile = new XmlDocument; docXMLFile->Load(S"Cars.xml"); // Get the root node so we can explore its children XmlNode *nodRoot = docXMLFile->DocumentElement; // If the car is not in the list already, create its Make node XmlNode *nodNewMake = docXMLFile->CreateNode(XmlNodeType::Element, S"Make", S""); // Create an attribute for the node dynamic_cast<XmlElement *>(nodNewMake)->SetAttribute(S"MakeName", strNewMake); // Add the new node to the XML file docXMLFile->DocumentElement->AppendChild(nodNewMake); // Save the file docXMLFile->Save(S"Cars.xml"); } } |
System::Void btnNewMake_Click(System::Object * sender, System::EventArgs * e) { // The new car make will come from the New Make dialog box NewMake *frmMake = new NewMake; // Display the New Make dialog box and find out if the user clicked OK if( frmMake->ShowDialog() == DialogResult::OK ) { String *strNewMake = frmMake->txtNewMake->Text; // If the user didn't create a new Make, don't do anything if( strNewMake->Equals(S"") ) return; // Before adding the new make, check that it doesn't exist already if( this->cboMakes->FindStringExact(strNewMake) > 0 ) return; // Now you can add it this->cboMakes->Items->Add(strNewMake); // The user likely wants this new item selected this->cboMakes->Text = strNewMake; // Open the Cars.xml file XmlDocument *docXMLFile = new XmlDocument; docXMLFile->Load(S"Cars.xml"); // Get the root node so we can explore its children XmlNode *nodRoot = docXMLFile->DocumentElement; // If the car is not in the list already, create its Make node XmlNode *nodNewMake = docXMLFile->CreateNode(XmlNodeType::Element, S"Make", S""); // Create an attribute for the node dynamic_cast<XmlElement *>(nodNewMake)->SetAttribute(S"MakeName", strNewMake); // Add the new node to the XML file docXMLFile->DocumentElement->AppendChild(nodNewMake); // Save the file docXMLFile->Save(S"Cars.xml"); } } |
System::Void btnNewModel_Click(System::Object * sender, System::EventArgs * e) { // The new car model will come from the New Model dialog box NewModel *frmModel = new NewModel; // Display the New Model dialog box and find out if the user clicked OK if( frmModel->ShowDialog() == DialogResult::OK ) { // Retrieve the values that the user specified String *strMake = frmModel->cboMakes->Text; String *strNewModel = frmModel->txtNewModel->Text; // If the user didn't select a Make, don't do anything if( strMake->Equals(S"") ) return; // If the New Model string is empty, don't do anything if( strNewModel->Equals(S"") ) return; // Open the Cars.xml file XmlDocument *docXMLFile = new XmlDocument; docXMLFile->Load(S"Cars.xml"); // Get the root node so we can explore its children XmlNode *nodRoot = docXMLFile->DocumentElement; // Create a list of all Make nodes XmlNodeList *lstMakes = docXMLFile->GetElementsByTagName(S"Make"); // Visit each Make for(int i = 0; i < lstMakes->Count; i++) { // Get a reference to the current node XmlNode *curMake = lstMakes->ItemOf[i]; // If, or when you find the Make if( curMake->Attributes->ItemOf[S"MakeName"]->InnerText->Equals(strMake) ) { // Since we found the Make, find out if the model exists XmlNodeList *lstCurrentModels = curMake->ChildNodes; // Check each model if the list already contains the model for(int j = 0; j < lstCurrentModels->Count; j++) { if( lstCurrentModels->ItemOf[j]->InnerText->Equals(strNewModel) ) { MessageBox::Show(S"That model exists already in the database"); return; } } // create a child node to it XmlNode *nodModel = docXMLFile->CreateNode(XmlNodeType::Element, S"Model", S""); // Create its value using the string from the New Make dialog box nodModel->InnerText = strNewModel; // Add the new element at the end of the file curMake->AppendChild(nodModel); // Save the file docXMLFile->Save(S"Cars.xml"); break; } } } } |
System::Void cboMakes_SelectedIndexChanged(System::Object * sender, System::EventArgs * e) { // Empty the Models combo box this->cboModels->Items->Clear(); // Find out if the user had selected a Make String *strSelectedMake = this->cboMakes->Text; // Open the Cars.xml file XmlDocument *docXML = new XmlDocument(); docXML->Load(S"Cars.xml"); // Get a reference to the root node XmlElement *nodRoot = docXML->DocumentElement; // Locate all nodes whose name is Make XmlNodeList *nodMakes = nodRoot->GetElementsByTagName(S"Make"); // Look for the Make that is the same the user selected for(int i = 0; i < nodMakes->Count; i++) { // Retrieve the value of each Make node and put String *strMakeName = nodMakes->ItemOf[i]->Attributes->ItemOf[S"MakeName"]->InnerText; // If you find it... if( strMakeName->Equals(strSelectedMake) ) { // If you find it, make a list of its models... XmlNodeList *nodAvailableModels = nodMakes->ItemOf[i]->ChildNodes; // ... then add each of its models to the Model combo box for(int j = 0; j < nodAvailableModels->Count; j++) this->cboModels->Items->Add(nodAvailableModels->ItemOf[j]->InnerText); } } } |
System::Void btnNewCategory_Click(System::Object * sender, System::EventArgs * e) { // Get a reference to the New Part Category form NewPartCategory *frmCategory = new NewPartCategory; // Display the New Part Category dialog box and find out if the user clicked OK if( frmCategory->ShowDialog() == DialogResult::OK ) { String *strCategory = frmCategory->txtNewCategory->Text; // If the user didn't create a new category, don't do anything if( strCategory->Equals(S"") ) return; // Before adding the new category, check that it doesn't exist already if( this->cboPartCategories->FindStringExact(strCategory) > 0 ) return; // Now you can add it this->cboPartCategories->Items->Add(strCategory); // The user likely wants this new item selected this->cboPartCategories->Text = strCategory; // Open the PartCategories.xml file XmlDocument *docXMLFile = new XmlDocument; docXMLFile->Load(S"PartCategories.xml"); // Get the root node so we can explore its children XmlNode *nodRoot = docXMLFile->DocumentElement; // If the new part is not in the list already, create its node XmlNode *nodNewCategory = docXMLFile->CreateNode(XmlNodeType::Element, S"PartCategory", S""); // Create text for the node nodNewCategory->InnerText = strCategory; // Add the new node to the XML file docXMLFile->DocumentElement->AppendChild(nodNewCategory); // Save the file docXMLFile->Save(S"PartCategories.xml"); } } |
System::Void txtPartName_TextChanged(System::Object * sender, System::EventArgs * e) { // If there is no part name, no need to add the item to the XML file if( this->txtPartName->Text->Equals(S"") ) this->btnAddPart->Enabled = false; else this->btnAddPart->Enabled = true; } |
System::Void txtUnitPrice_TextChanged(System::Object * sender, System::EventArgs * e) { // If the price is not specified, don't add the item to the XML file if( this->txtUnitPrice->Text->Equals(S"") ) this->btnAddPart->Enabled = false; else this->btnAddPart->Enabled = true; } |
System::Void txtPartNumber_TextChanged(System::Object * sender, System::EventArgs * e) { // Make sure that there is a Part Number for this item // Otherwise, don't add the part to the XML file if( this->txtPartNumber->Text->Equals(S"") ) this->btnAddPart->Enabled = false; else this->btnAddPart->Enabled = true; } |
System::Void btnAddPart_Click(System::Object * sender, System::EventArgs * e) { // Open the Parts.xml file XmlDocument *docXML = new XmlDocument(); docXML->Load(S"Parts.xml"); // Before adding the new part, make sure all components are ready // Otherwise, don't add it if( this->cboYears->SelectedIndex < 0 ) { MessageBox::Show(S"You must specify the year. " S"This will help to locate the part"); this->cboYears->Focus(); return; } if( this->cboMakes->SelectedIndex < 0 ) { MessageBox::Show(S"Please select the car make for this part."); this->cboMakes->Focus(); return; } if( this->cboModels->SelectedIndex < 0 ) { MessageBox::Show(S"The car model is required. " S"It helps to know the specific car this part is made for."); this->cboModels->Focus(); return; } if( this->txtPartName->Text->Equals(S"") ) { MessageBox::Show(S"You must specify the part name or a (very) short description."); this->txtPartName->Focus(); return; } if( this->txtUnitPrice->Text->Equals(S"") ) { MessageBox::Show(S"You must enter the price of each unit of this part."); this->txtUnitPrice->Focus(); return; } if( this->txtPartNumber->Text->Equals(S"") ) { MessageBox::Show(S"Every item of this database must have a number. " S"The number is just a combination of letters and digits." S"Please make up a number and enter it in the Part # box."); this->txtPartNumber->Focus(); return; } // The part seems to be ready // Get a reference to the root node XmlElement *nodNewPart = docXML->CreateElement(S"Part"); // Create a new part as a child of the root (this is a simple node addition) String *strNewPart = String::Concat(S"<PartNumber>", this->txtPartNumber->Text, S"</PartNumber>", S"<CarYear>", this->cboYears->Text, S"</CarYear>", S"<Make>", this->cboMakes->Text, S"</Make>", S"<Model>", this->cboModels->Text, S"</Model>", S"<PartName Category=\"", this->cboPartCategories->Text,S"\">", this->txtPartName->Text, S"</PartName>", S"<UnitPrice>", this->txtUnitPrice->Text, S"</UnitPrice>"); nodNewPart->InnerXml = strNewPart; docXML->DocumentElement->AppendChild(nodNewPart); docXML->Save(S"Parts.xml"); // Reset the form in case the user wants to add another part this->cboYears->SelectedIndex = -1; this->cboMakes->SelectedIndex = -1; this->cboModels->SelectedIndex = -1; this->cboPartCategories->Text = S"Miscellaneous"; this->txtPartName->Text = S""; this->txtUnitPrice->Text = S""; // We will generate a random number for the item // To start, we will use the miliseconds as a seed DateTime tmeNow = DateTime::Now; int ms = tmeNow.Millisecond; // Now we can generate a random number between 100000 and 999999 Random *rndNumber = new Random(ms); // Generate three random characters Char firstCharacter = static_cast<Char>(rndNumber->Next(65, 90)); Char secondCharacter = static_cast<Char>(rndNumber->Next(65, 90)); Char thirdCharacter = static_cast<Char>(rndNumber->Next(65, 90)); // Generate a random number made of 4 digits int numberPart = rndNumber->Next(1000, 9999); // Exclude the digits 1 and 0 because they create confusion if( firstCharacter == 'I' || firstCharacter == 'O' ) firstCharacter = 'A'; if( secondCharacter == 'I' || secondCharacter == 'O' ) secondCharacter = 'A'; if( thirdCharacter == 'I' || thirdCharacter == 'O' ) thirdCharacter = 'A'; // Generate a random number between 1 and 3 int rndCombination = rndNumber->Next(1, 4); String *strPartNumber = 0; // Create a part number using some algorithm if( rndCombination == 1 ) strPartNumber = String::Concat(firstCharacter.ToString(), secondCharacter.ToString(), numberPart.ToString(), thirdCharacter.ToString()); else if( rndCombination == 2 ) strPartNumber = String::Concat(firstCharacter.ToString(), numberPart.ToString(), secondCharacter.ToString(), thirdCharacter.ToString()); else if( rndCombination == 3 ) strPartNumber = String::Concat(numberPart.ToString(), firstCharacter.ToString(), secondCharacter.ToString(), thirdCharacter.ToString()); else strPartNumber = rndNumber->Next(100000, 999999).ToString(); // Display the new number in the Part # text box this->txtPartNumber->Text = strPartNumber; this->cboYears->Focus(); } |
Year | Make | Model | Part Category | Part Name | Unit Price |
2002 | Audi | A4 Quattro 1.8L Turbo | Exhaust | Exhaust Gasket | 1.55 |
2004 | Dodge | Neon SE 2.0L L4 | Cooling System | Radiator Fan Assembly | 125.95 |
2002 | Audi | A4 Quattro 1.8L Turbo | Drivetrain | Axle Differential Bearing - Left | 10.25 |
2000 | Ford | Escort 2.0L L4 | Ignition | Crankshaft Position Sensor | 18.65 |
2002 | Chevrolet | Silverado 2500 5.3L V8 | Ignition | Spark Plugs | 1.55 |
2004 | Dodge | Neon SE 2.0L L4 | Engine | Oil Pump | 112.85 |
2004 | Dodge | Neon SE 2.0L L4 | Engine | Exhaust Valve | 5.85 |
1986 | Acura | Integra LS 1.8L L4 | Electrical | Alternator | 110.75 |
1998 | Toyota | Corolla 1.8L L4 | Cooling System | Radiator | 95.95 |
2002 | Dodge | Dakota 3.9L V6 | Electrical | Starter Motor | 145.95 |
2004 | Honda | Civic EX 1.7L L4 | Emission | Oxygen Sensor | 90.55 |
2002 | Audi | A4 Quattro 1.8L Turbo | Electrical | Alternator | 305.50 |
2002 | Acura | NSX 3.0L V6 | Engine | Oil Filter | 7.05 |
1998 | Jeep | Wrangler 2.5L L4 | Transfer Case | Input Shaft Seal Transfer Case | 6.45 |
1986 | Acura | Integra LS 1.8L L4 | Fuel/Air | Fuel Cap (Regular) | 4.15 |
2000 | Ford | Escort 2.0L L4 | Brake System | Right Caliper Assembly Front | 32.85 |
2004 | Dodge | Neon SE 2.0L L4 | Clutch | Clutch Release Bearing | 25.75 |
1998 | BMW | 325I 2.5L L6 | Steering | Rack and Pinion Bellow Kit | 19.25 |
2001 | Acura | Integra GS 1.8L L4 | Electrical | Voltage Regulator | 215.75 |
2001 | Audi | S4 2.7L V6 | Engine | Timing Belt | 35.95 |
2002 | Audi | A4 Quattro 1.8L Turbo | Exhaust | Muffler Hanger | 3.35 |
2002 | Chevrolet | Silverado 2500 5.3L V8 | Cooling System | Radiator w/Air Tube - w/TOC | 215.75 |
2002 | Acura | NSX 3.0L V6 | Engine | Oil Drain Plug | 1.35 |
2002 | Dodge | Dakota 3.9L V6 | Electrical | Circuit Breaker | 3.25 |
2004 | Dodge | Neon SE 2.0L L4 | Brake System | Brake Pad | 20.55 |
2004 | Honda | Civic EX 1.7L L4 | Electrical | Fusible Link | 3.35 |
2002 | Dodge | Dakota 3.9L V6 | Electrical | Circuit Breaker | 3.45 |
2004 | Honda | Civic EX 1.7L L4 | Transmission-Manual | Differential Bearing | 36.75 |
1998 | Toyota | Corolla 1.8L L4 | Cooling System | Thermostat Standard Temperature | 9.35 |
2002 | Audi | A4 Quattro 1.8L Turbo | Electrical | Cooling Fan Sensor | 8.65 |
2002 | Acura | NSX 3.0L V6 | Engine | Oil Pump Seal | 12.55 |
2004 | Dodge | Neon SE 2.0L L4 | Brake System | Master Cylinder w/o ABS w/2 Wheel | 102.95 |
2002 | Acura | NSX 3.0L V6 | Engine | Valve Stem Oil Seal | 1.75 |
2002 | Dodge | Dakota 3.9L V6 | Electrical | Fuse | 0.40 |
1998 | Toyota | Corolla 1.8L L4 | Cooling System | Regular Thermostat | 11.15 |
|
||
Previous | Copyright © 2004-2016, FunctionX, Inc. | Next |
|