Fundamentals of Attributes

Introduction

When studying XML elements we saw how they constituted the main objects of an XML document. We also saw that an element could be nested inside of another element. Instead of nesting an element, you can transform the nested element into being part of the nesting element and thereby giving away its element qualities. This is the basis of an attribute.

An attribute is a value that is created as part of an element, making that value different from the value of a regular element. There are similarities and differences between an element and an attribute.

The element and the attribute have these in common:

The differences between an element and an attribute are:

This is one more version of a web project for a fictitious company that makes and sells office chairs. Each chair has a weight and a price. A customer can order a certain number of chairs, which results in a calculated sub-total (the number of chairs multiplied by the price of a chair). When acustomer places an order, a discount is based on the sub-total amount of the order. The shipping and handling of a customer order is based on the total weight of the chairs ordered.

Practical LearningPractical Learning: Introducing XML Attributes

  1. Start Microsoft Visual Studio
  2. On the main menu, click File -> New -> Project ...
  3. In the New Project dialog box, make sure ASP.NET Web Application (.NET Framework) is selected. Change the Name to ChairExecs1
  4. Press Enter
  5. In the New ASP.NET Web Application dialog box, click the MVC icon and click OK
  6. In the Solution Explorer, right-click ChairExecs1 -> Add -> New Folder
  7. Type Images and press Enter
  8. Copy and paste the following pictures to the Images folder:
     
    Background Picture
    Chair Chair Chair
  9. In the Solution Explorer, right-click Content -> Add -> New Item...
  10. In the Add New Item dialox box, click Style Sheet and change the file Name to ChairExecs
  11. Click Add
  12. Change the document as follows:
    body {
    }
    
    .bottom-bar {
        left:             0;
        right:            0;
        bottom:           0;
        margin-bottom:    0;
        position:         fixed;
        background-color: #033e65;
        border-top:       6px solid #e0a43a; }
    
    .top-banner {
        margin:           auto;
        min-width:        800px;
        max-width:        1150px;
        height:           13.50em;
        border-bottom-left-radius: 30px;
        border-bottom-right-radius: 30px;
        border-bottom:    30px;
        background-color: #033e65;
        border-left:      2px solid #0A2DD5;
        border-right:     2px solid #0A2DD5;
        border-bottom:    2px solid #0A2DD5;
        background-image: url(../Images/bg2.png)
    }
    
    .top-table          { margin-top:       0px;
                          margin-left:      50px;
                          width:            800px;     }
    .copyright          { color:            aliceblue;
                          text-align:       center;    }
    .col-md-3 > h4      { color:            #e0eaf2;
                          margin-left:      40px;      }
    .col-md-3 > h4 > ul { list-style-type:  none;      }
    .bottom-row         { margin:           auto;
                          min-width:        800px;
                          max-width:        1150px;    }
    .navbar-fixed-top   { height:           10.50em;
                          background-color: #033E65;
                          border-bottom:    3px solid #0A2DD5; }
    .jumbotron          { padding-bottom:   10px;
                          background-color: #FFF;
                          padding-top:      180px;   }
    .jumbotron h1       { color:            #0a2dd5; }
    .lead               { color:            #071b96; }
    .col-head           { font-weight:      600;
                          font-size:        18px;
                          color:            #800000; }
  13. In the Solution Explorer, under Views, expand Shared and double-click Layout.cshtml
  14. Change the file as follows:
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - Chair Executives</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
    <link rel="stylesheet" type="text/css" href="~/Content/ChairExecs.css" />
    </head>
    <body>
        <div class="navbar-fixed-top">
            <div class="top-banner">
                &nbsp;
                <table class="top-table">
                    <tr>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                        <td rowspan="7"></td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                    </tr>
                    <tr>
                        <td>@Html.ActionLink("Home", "Index", "Home")</td>
                        <td>@Html.ActionLink("Our Brand", "OurBrand", "Home")</td>
                        <td>@Html.ActionLink("School Deals", "SchoolDeals", "Home")</td>
                    </tr>
                    <tr>
                        <td>@Html.ActionLink("About Us", "About", "Home")</td>
                        <td>@Html.ActionLink("Our Materials", "LearnMore", "Home")</td>
                        <td>@Html.ActionLink("Small Business Deals", "SmallBusinessDeals", "Home")</td>
                    </tr>
                    <tr>
                        <td>@Html.ActionLink("Contact Us", "Contact", "Home")</td>
                        <td>@Html.ActionLink("Our Designs", "CurrentSales", "Home")</td>
                        <td>@Html.ActionLink("Enterprise Deals", "EnterpriseDeals", "Home")</td>
                    </tr>
                    <tr>
                        <td>@Html.ActionLink("Customer Service", "CustomerService", "Home")</td>
                        <td>@Html.ActionLink("Our Customers", "Customers", "Home")</td>
                        <td>@Html.ActionLink("Government Deals", "GovernmentDeals", "Home")</td>
                    </tr>
                </table>
            </div>
        </div>
    
        <div class="container body-content">
            @RenderBody()
            <hr />
            <footer class="bottom-bar">
                <div class="bottom-row">
                    <div class="col-md-3">
                        <h4>Departments</h4>
                        <ul>
                            <li>@Html.ActionLink("Shop by Category", "Category", "Shop")</li>
                            <li>@Html.ActionLink("Shop by Brand", "Brand", "Shop")</li>
                            <li>@Html.ActionLink("Shop by Material", "Material", "Shop")</li>
                            <li>@Html.ActionLink("Shop by Environment", "Environment", "Shop")</li>
                        </ul>
                    </div>
                    <div class="col-md-3">
                        <h4>Accounts</h4>
                        <ul>
                            <li>@Html.ActionLink("Login", "Personal", "Home")</li>
                            <li>@Html.ActionLink("Register/Create Account", "School", "Home")</li>
                            <li>@Html.ActionLink("Club Membership", "Membership", "Home")</li>
                            <li>@Html.ActionLink("Privacy Issues", "Index", "Home")</li>
                        </ul>
                    </div>
                    <div class="col-md-3">
                        <h4>Solutions</h4>
                        <ul>
                            <li>@Html.ActionLink("Classic", "Index", "Home")</li>
                            <li>@Html.ActionLink("Exotic", "About", "Home")</li>
                            <li>@Html.ActionLink("Essentials", "Contact", "Home")</li>
                            <li>@Html.ActionLink("Ergonomic Economy", "Index", "Home")</li>
                        </ul>
                    </div>
                    <div class="col-md-3">
                        <h4>Relations</h4>
                        <ul>
                            <li>@Html.ActionLink("Public relations", "Index", "Home")</li>
                            <li>@Html.ActionLink("Press Releases", "About", "Home")</li>
                            <li>@Html.ActionLink("Legislations/Regulations", "Contact", "Home")</li>
                            <li>@Html.ActionLink("Newsletter Subscription", "Index", "Home")</li>
                        </ul>
                    </div>
                    <hr />
                    <p class="copyright">&copy; @DateTime.Now.Year - Chair Executives</p>
                </div>
            </footer>
        </div>
    
        @Scripts.Render("~/bundles/jquery")
        @Scripts.Render("~/bundles/bootstrap")
        @RenderSection("scripts", required: false)
    </body>
    </html>
  15. In the Solution Explorer, expand Views and expand Home
  16. Under Views, double-click Index.cshtml to open it
  17. Change the document as follows:
    @{
        ViewBag.Title = "Welcome to Chair Executives";
    }
    
    <div class="jumbotron">
        <p class="lead">At Chair Executives, we design, create, manufacture, and care for
            comfortable chairs for home offices, schools, small businesses, enterprises,
            and government environments. Through rigorous research and tests, we
            understand what various users look for in a chair. We certainly
            know and have what it takes to fulfill your long seating needs.</p>
    </div>
    
    <table style="width: 100%">
        <tr>
            <td colspan="2" style="width: 33%"><P class="col-head">Attentive Seating</P></td>
            <td colspan="2" style="width: 33%"><P class="col-head">Spirit of Monarchy</P></td>
            <td colspan="2" style="width: 100%"><P class="col-head">Confidence n&#039; Management</P></td>
        </tr>
        <tr>
            <td><img src="~/Images/chair1a.png" /></td>
            <td>
                <p>This introductory chair&#039;s primary goal is to serve short-seating
                    periods (such as job interviews or classroom teachers) environments
                    not concerned with rough use.</p>
            </td>
            <td><img src="~/Images/chair1b.png" alt="Business Chairs" /></td>
            <td>
                <p>This is our intermediate chair aimed at business offices, enterprises,
                    and the government. This category of chairs provide warmth comfort for long use.</p>
            </td>
            <td><img src="~/Images/chair1c.png" alt="Business Chairs" /></td>
            <td>
                <p>Our top executive chair provides the ultimate comfort. Its goal is
                    to assist business managers and supervisors who must spend long
                    hours seating and making important decisions.</p>
            </td>
        </tr>
    </table>
  18. To execute the project, on the main menu, click Debug -> Start Without Debugging

    Delegates and Parameters

  19. Close the browser and return to your programming environment
  20. In the Solution Explorer, right-click Models -> Add -> New Item...
  21. In the left frame of the Add New Item dialog box, click Code
  22. In the middle frame, click Code File
  23. Change the file Name to Basic
  24. Click Add
  25. Create an enumeration as follows:
    namespace ChairExecs1.Models
    {
        public enum Basic
        {
            Station,
            Essential,
            Instructor
        }
    }
  26. In the Solution Explorer, right-click Controllers -> Add -> New Scaffolded Item...
  27. In the Add Scaffold dialog box, click MVC 5 Controller - Empty. Click Add
  28. Type Business to get BusinessController
  29. Click Add
  30. Add a method as follows:
    using System.IO;
    using System.Xml;
    using System.Web.Mvc;
    using System.Collections.Generic;
    
    namespace ChairExecs1.Controllers
    {
        public class BusinessController : Controller
        {
            // GET: Business
            public ActionResult Index()
            {
                return View();
            }
    
            // GET: Business/StartCustomerOrder
            public ActionResult StartCustomerOrder()
            {
                List<SelectListItem> execs = new List<SelectListItem>();
    
                execs.Add(new SelectListItem() { Text = "Excel Extent", Value = "Excel Extent" });
                execs.Add(new SelectListItem() { Text = "Executive", Value = "Executive" });
    
                ViewData["Executive"] = execs;
    
                return View();
            }
    
            // GET: Business/PrepareCustomerOrder
            public ActionResult PrepareCustomerOrder(string Type1Name, string Type1UnitWeight, string Type1UnitPrice, string Type1Quantity,
                                                     string Type2Name, string Type2UnitWeight, string Type2UnitPrice, string Type2Quantity,
                                                     string Type3Name, string Type3UnitWeight, string Type3UnitPrice, string Type3Quantity)
            {
                int receiptNumber = 100000;
                FileStream fsCustomersOrders = null;
                XmlDocument xdCustomersOrders = new XmlDocument();
                string customersOrders = Server.MapPath("~/App_Data/CustomersOrders.xml");
    
                if (!string.IsNullOrEmpty(Type1Name))
                {
                    int iType1Weight = int.Parse(Request["Type1UnitWeight"]);
                    int iType1Quantity = int.Parse(Request["Type1Quantity"]);
                    double dType1UnitPrice = double.Parse(Request["Type1UnitPrice"]);
    
                    int iType2Weight = int.Parse(Request["Type2UnitWeight"]);
                    int iType2Quantity = int.Parse(Request["Type2Quantity"]);
                    double dType2UnitPrice = double.Parse(Request["Type2UnitPrice"]);
    
                    int iType3Weight = int.Parse(Request["Type3UnitWeight"]);
                    int iType3Quantity = int.Parse(Request["Type3Quantity"]);
                    double dType3UnitPrice = double.Parse(Request["Type3UnitPrice"]);
    
                    int type1TotalWeight = 0, type2TotalWeight = 0, type3TotalWeight = 0;
    
                    if (iType1Quantity == 0)
                        type1TotalWeight = 0;
                    else
                        type1TotalWeight = iType1Weight * iType1Quantity;
    
                    if (iType2Quantity == 0)
                        type2TotalWeight = 0;
                    else
                        type2TotalWeight = iType2Weight * iType2Quantity;
    
                    if (iType3Quantity == 0)
                        type3TotalWeight = 0;
                    else
                        type3TotalWeight = iType3Weight * iType3Quantity;
    
                    if (System.IO.File.Exists(customersOrders))
                    {
                        using (fsCustomersOrders = new FileStream(customersOrders, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            xdCustomersOrders.Load(fsCustomersOrders);
    
                            XmlNodeList xnlCustomersOrders = xdCustomersOrders.GetElementsByTagName("receipt-number");
    
                            foreach (XmlNode xnCustomerOrder in xnlCustomersOrders)
                            {
                                receiptNumber = int.Parse(xnCustomerOrder.InnerText);
                            }
                        }
                    }
    
                    receiptNumber++;
    
                    ViewData["ReceiptNumber"] = receiptNumber;
                    ViewData["Type1Quantity"] = Type1Quantity;
                    ViewData["Type2Quantity"] = Type2Quantity;
                    ViewData["Type3Quantity"] = Type3Quantity;
                    ViewData["Type1SubTotal"] = dType1UnitPrice * iType1Quantity;
                    ViewData["Type2SubTotal"] = dType2UnitPrice * iType2Quantity;
                    ViewData["Type3SubTotal"] = dType3UnitPrice * iType3Quantity;
                    ViewData["Type1TotalWeight"] = type1TotalWeight;
                    ViewData["Type2TotalWeight"] = type2TotalWeight;
                    ViewData["Type3TotalWeight"] = type3TotalWeight;
                    ViewData["TotalWeight"] = iType1Weight + iType2Weight + iType3Weight;
                }
    
                return View();
            }
    
            // GET: Business/SaveCustomerOrder
            public ActionResult SaveCustomerOrder(string ReceiptNumber,
                                                  string Type1Name, string Type1UnitWeight, string Type1UnitPrice, string Type1Quantity, string Type1TotalWeight, string Type1SubTotal,
                                                  string Type2Name, string Type2UnitWeight, string Type2UnitPrice, string Type2Quantity, string Type2TotalWeight, string Type2SubTotal,
                                                  string Type3Name, string Type3UnitWeight, string Type3UnitPrice, string Type3Quantity, string Type3TotalWeight, string Type3SubTotal,
                                                  string TotalWeight, string SubTotal, string DiscountRate, string DiscountAmount, string ShippingAndHandling, string OrderTotal)
            {
                FileStream fsCustomersOrders = null;
                XmlDocument xdCustomersOrders = new XmlDocument();
                string customersOrders = Server.MapPath("~/App_Data/CustomersOrders.xml");
    
                if (!string.IsNullOrEmpty(ReceiptNumber))
                {
                    if (System.IO.File.Exists(customersOrders))
                    {
                        using (fsCustomersOrders = new FileStream(customersOrders, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            xdCustomersOrders.Load(fsCustomersOrders);
                        }
                    }
                    else
                    {
                        xdCustomersOrders.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                                                  "<customers-orders></customers-orders>");
                    }
    
                    XmlElement xeCustomerOrder = xdCustomersOrders.CreateElement("customer-order");
    
                    xeCustomerOrder.InnerXml = "<receipt-number>" + ReceiptNumber + "</receipt-number>" +
                                               "<type1-name>" + Type1Name + "</type1-name>" +
                                               "<type1-unit-weight>" + Type1UnitWeight + "</type1-unit-weight>" +
                                               "<type1-unit-price>" + Type1UnitPrice + "</type1-unit-price>" +
                                               "<type1-quantity>" + Type1Quantity + "</type1-quantity>" +
                                               "<type1-total-weight>" + Type1TotalWeight + "</type1-total-weight>" +
                                               "<type1-sub-total>" + Type1SubTotal + "</type1-sub-total>" +
                                               "<type2-name>" + Type2Name + "</type2-name>" +
                                               "<type2-unit-weight>" + Type2UnitWeight + "</type2-unit-weight>" +
                                               "<type2-unit-price>" + Type2UnitPrice + "</type2-unit-price>" +
                                               "<type2-quantity>" + Type2Quantity + "</type2-quantity>" +
                                               "<type2-total-weight>" + Type2TotalWeight + "</type2-total-weight>" +
                                               "<type2-sub-total>" + Type2SubTotal + "</type2-sub-total>" +
                                               "<type3-name>" + Type3Name + "</type3-name>" +
                                               "<type3-unit-weight>" + Type3UnitWeight + "</type3-unit-weight>" +
                                               "<type3-unit-price>" + Type3UnitPrice + "</type3-unit-price>" +
                                               "<type3-quantity>" + Type3Quantity + "</type3-quantity>" +
                                               "<type3-total-weight>" + Type3TotalWeight + "</type3-total-weight>" +
                                               "<type3-sub-total>" + Type3SubTotal + "</type3-sub-total>" +
                                               "<total-weight>" + TotalWeight + "</total-weight>" +
                                               "<sub-total>" + SubTotal + "</sub-total>" +
                                               "<discount-rate>" + DiscountRate + "</discount-rate>" +
                                               "<discount-amount>" + DiscountAmount + "</discount-amount>" +
                                               "<shipping-and-handling>" + ShippingAndHandling + "</shipping-and-handling>" +
                                               "<order-total>" + OrderTotal + "</order-total>";
    
                    xdCustomersOrders.DocumentElement.AppendChild(xeCustomerOrder);
    
                    using (fsCustomersOrders = new FileStream(customersOrders, FileMode.Create, FileAccess.Write, FileShare.Write))
                    {
                        xdCustomersOrders.Save(fsCustomersOrders);
                    }
    
                }
    
                return RedirectToAction("StartCustomerOrder");
            }
        }
    }
  31. In the document, right-click StartCustomerOrder and click Add View...
  32. In the dialog box, make sure the text box displays StartCustomerOrder and click Add
  33. Create a form as follows:
    @{
        ViewBag.Title = "New Customer Order";
    }
    
    <div align="center">
        <h2 style="margin-top: 6.5em">New Customer Order</h2>
    
        @using (Html.BeginForm("PrepareCustomerOrder", "Business", FormMethod.Post))
        {
            var Type2Name = new List<SelectListItem>()
            {
                new SelectListItem { Text = "Scholar",    Value = "Scholar", },
                new SelectListItem { Text = "Conviction", Value = "Conviction", }
            };
    
        <table>
            <tr>
                <td style="width: 120px"><b>Item Name</b></td>
                <td><b>Weight</b></td>
                <td><b>Unit Price</b></td>
                <td><b>Quantity</b></td>
            </tr>
            <tr>
                <td>@Html.DropDownList("Type1Name",
                                       new SelectList(Enum.GetValues(typeof(ChairExecs1.Models.Basic))),
                                       new { style = "width: 160px" })</td>
                <td>@Html.TextBox("Type1UnitWeight", "28", new { style = "width: 55px" }) Lbs</td>
                <td>@Html.TextBox("Type1UnitPrice", "64.95", new { style = "width: 75px" })</td>
                <td>@Html.TextBox("Type1Quantity", "0", new { style = "width: 55px" })</td>
            </tr>
            <tr>
                <td>@Html.DropDownList("Type2Name", Type2Name, new { style = "width: 160px" })</td>
                <td>@Html.TextBox("Type2UnitWeight", "36", new { style = "width: 55px" }) Lbs</td>
                <td>@Html.TextBox("Type2UnitPrice", "104.45", new { style = "width: 75px" })</td>
                <td>@Html.TextBox("Type2Quantity", "0", new { style = "width: 55px" })</td>
            </tr>
            <tr>
                <td>@Html.DropDownList("Type3Name", null, new { style = "width: 160px" })</td>
                <td>@Html.TextBox("Type3UnitWeight", "54", new { style = "width: 55px" }) Lbs</td>
                <td>@Html.TextBox("Type3UnitPrice", "154.55", new { style = "width: 75px" })</td>
                <td>@Html.TextBox("Type3Quantity", "0", new { style = "width: 55px" })</td>
            </tr>
        </table>
    
        <hr />
    
        <p style="text-align: center; width: 500px">
            <input type="submit" name="btnPrepareCustomerOrder"
                   value="Prepare Customer Order" style="width: 300px" />
        </p>
        }
    </div>
  34. In the Solution Explorer, under Views, right-click Business -> Add -> New Scaffolded Item...
  35. In the Add Scaffold dialog box, click MVC 5 View
  36. Click Add
  37. Type PrepareCustomerOrder as the name of the view
  38. Click Add
  39. Change the document as follows:
    @{
        ViewBag.Title = "Prepare Customer Order";
    }
    
    @{
        int receiptNumber = int.Parse(ViewData["ReceiptNumber"].ToString());
        double discountRate = 0.00, shipping = 0.00;
    
        double subTotal1 = double.Parse(ViewData["Type1SubTotal"].ToString());
        double subTotal2 = double.Parse(ViewData["Type2SubTotal"].ToString());
        double subTotal3 = double.Parse(ViewData["Type3SubTotal"].ToString());
    
        double totalWeight = double.Parse(ViewData["TotalWeight"].ToString());
    
        double subTotal = subTotal1 + subTotal2 + subTotal3;
    
        if (subTotal >= 800)
        {
            discountRate = 20; // %
        }
        else if (subTotal >= 600)
        {
            discountRate = 15; // %
        }
        else if (subTotal >= 300)
        {
            discountRate = 10; // %
        }
        else
        {
            discountRate = 0; // %
        }
    
        if (totalWeight >= 200)
        {
            shipping = 42.50;
        }
        else if (totalWeight >= 150)
        {
            shipping = 36.25;
        }
        else if (totalWeight >= 100)
        {
            shipping = 24.48;
        }
        else if (totalWeight >= 50)
        {
            shipping = 18.65;
        }
        else
        {
            shipping = 12.25;
        }
    
        double discountAmount = subTotal * discountRate / 100;
        double orderTotal = subTotal - discountAmount + shipping;
    }
    
    <div align="center">
        <h2 style="margin-top: 6.5em">Prepare Customer Order</h2>
    
        @using (Html.BeginForm("SaveCustomerOrder", "Business", FormMethod.Post))
        {
            <table style="width: 540px;">
                <tr>
                    <td style="width: 350px; font-size: 14px; border-bottom: 2px double black; font-weight: bold; text-align: center">Item Definition</td>
                    <td style="border-bottom: 2px double black; font-size: 14px; font-weight: bold">Sale Description</td>
                </tr>
            </table>
            <table>
                <tr>
                    <td style="width: 120px"><b>Item Name</b></td>
                    <td><b>Weight</b></td>
                    <td><b>Unit Price</b></td>
                    <td><b>Quantity</b></td>
                    <td><b>Weight</b></td>
                    <td><b>Sub-Total</b></td>
                </tr>
                <tr>
                    <td>@Html.TextBox("Type1Name", @"Type1Name")</td>
                    <td>@Html.TextBox("Type1UnitWeight", @"Type1UnitWeight", new { style = "width: 55px" }) Lbs</td>
                    <td>@Html.TextBox("Type1UnitPrice", @"Type1UnitPrice", new { style = "width: 75px" })</td>
                    <td>@Html.TextBox("Type1Quantity", @ViewData["Type1Quantity"], new { style = "width: 55px" })</td>
                    <td>@Html.TextBox("Type1TotalWeight", @ViewData["Type1TotalWeight"], new { style = "width: 55px" }) Lbs</td>
                    <td>@Html.TextBox("Type1SubTotal", @subTotal1.ToString("F"), new { style = "width: 75px" })</td>
                </tr>
                <tr>
                    <td>@Html.TextBox("Type2Name", @"Type2Name")</td>
                    <td>@Html.TextBox("Type2UnitWeight", @"Type2UnitWeight", new { style = "width: 55px" }) Lbs</td>
                    <td>@Html.TextBox("Type2UnitPrice", @"Type2UnitPrice", new { style = "width: 75px" })</td>
                    <td>@Html.TextBox("Type2Quantity", @ViewData["Type2Quantity"], new { style = "width: 55px" })</td>
                    <td>@Html.TextBox("Type2TotalWeight", @ViewData["Type2TotalWeight"], new { style = "width: 55px" }) Lbs</td>
                    <td>@Html.TextBox("Type2SubTotal", @subTotal2.ToString("F"), new { style = "width: 75px" })</td>
                </tr>
                <tr>
                    <td>@Html.TextBox("Type3Name", @"Type3Name")</td>
                    <td>@Html.TextBox("Type3UnitWeight", @"Type3UnitWeight", new { style = "width: 55px" }) Lbs</td>
                    <td>@Html.TextBox("Type3UnitPrice", @"Type3UnitPrice", new { style = "width: 75px" })</td>
                    <td>@Html.TextBox("Type3Quantity", @ViewData["Type3Quantity"], new { style = "width: 55px" })</td>
                    <td>@Html.TextBox("Type3TotalWeight", @ViewData["Type3TotalWeight"], new { style = "width: 55px" }) Lbs</td>
                    <td>@Html.TextBox("Type3SubTotal", @subTotal3.ToString("F"), new { style = "width: 75px" })</td>
                </tr>
            </table>
            <hr />
            <table>
                <tr>
                    <td style="width: 160px">Total Weight:</td>
                    <td>@Html.TextBox("TotalWeight", @totalWeight, new { style = "width: 75px" }) Lbs</td>
                    <td style="width: 80px">&nbsp;</td>
                    <td>Sub-Total:</td>
                    <td>@Html.TextBox("SubTotal", @subTotal.ToString("F"), new { style = "width: 75px" })</td>
                </tr>
                <tr>
                    <td>Discount Rate:</td>
                    <td>@Html.TextBox("DiscountRate", @discountRate.ToString("F"), new { style = "width: 75px" })%</td>
                    <td>&nbsp;</td>
                    <td>Discount Amount:</td>
                    <td>@Html.TextBox("DiscountAmount", @discountAmount.ToString("F"), new { style = "width: 75px" })</td>
                </tr>
                <tr>
                    <td>Shipping &amp; Handling:</td>
                    <td>@Html.TextBox("ShippingAndHandling", @shipping.ToString("F"), new { style = "width: 75px" })</td>
                    <td>&nbsp;</td>
                    <td>Order Total:</td>
                    <td>@Html.TextBox("OrderTotal", @orderTotal.ToString("F"), new { style = "width: 75px" })</td>
                </tr>
            </table>
    
            <hr />
    
            <table>
                <tr>
                    <td style="width: 160px; text-align: right">Receipt #:</td>
                    <td>@Html.TextBox("ReceiptNumber", @receiptNumber, new { style = "width: 75px" })</td>
                    <td style="width: 80px">&nbsp;</td>
                    <td><input type="submit" name="btnSaveCustomerOrder"
                               value="Save Customer Order" style="width: 200px" /></td>
                </tr>
            </table>
        }
    </div>
  40. Click the StartCustomerOrder.cshtml tab to access it
  41. To execute the project, on the main menu, click Debug ->Start Without Debugging:

    Viewing Data in a View

  42. In the first combo box, select Essential and set the corresponding quantity to 3
  43. For the second combo box, set the values as follows:
    Weight:      44
    Unit Price:  105.25
    Quantity:    2
  44. For the 3rd combo box, set the corresponding values as follows:
    Weight:     58
    Unit Price: 214.85
    Quantity:   6

    Viewing Data in a View

  45. Click the Prepare Customer Order button:

    Introducing Interfaces

  46. Click the Save Customer Order button:
    <?xml version="1.0" encoding="utf-8"?>
    <customers-orders>
      <customer-order>
        <receipt-number>100001</receipt-number>
        <type1-name>Demeanor</type1-name>
        <type1-unit-weight>16</type1-unit-weight>
        <type1-unit-price>64.95</type1-unit-price>
        <type1-quantity>3</type1-quantity>
        <type1-total-weight>48</type1-total-weight>
        <type1-sub-total>194.85</type1-sub-total>
        <type2-name>Scholar</type2-name>
        <type2-unit-weight>32</type2-unit-weight>
        <type2-unit-price>104.45</type2-unit-price>
        <type2-quantity>3</type2-quantity>
        <type2-total-weight>96</type2-total-weight>
        <type2-sub-total>313.35</type2-sub-total>
        <type3-name>Executive</type3-name>
        <type3-unit-weight>36</type3-unit-weight>
        <type3-unit-price>154.55</type3-unit-price>
        <type3-quantity>5</type3-quantity>
        <type3-total-weight>180</type3-total-weight>
        <type3-sub-total>772.75</type3-sub-total>
        <total-weight>84</total-weight>
        <sub-total>1280.95</sub-total>
        <discount-rate>20.00</discount-rate>
        <discount-amount>256.19</discount-amount>
        <shipping-and-handling>18.65</shipping-and-handling>
        <order-total>1043.41</order-total>
      </customer-order>
    </customers-orders>
  47. Close the browser and return to your programming environment
  48. On the toolbar of the Solution Explorer, click the Show All Files button Show All Files
  49. Still in the Solution Explorer, expand App_Data, right-click CustomersOrders.xml and click Delete
  50. On the message box, click OK
  51. Click the BusinessController.cs.cs tab to activate it

XML Attributes in .NET

To support XML attributes, the System.Xml namespace provides a class named XmlAttribute. Like all nodes, this class is based on the XmlNode class.

The Name of an Attribute

To let you get the name of an attribute, the XmlAttribute class is equipped with a (read-only) property named Name.

The Inner Text of an Attribute

To let you get the value of an attribute, the XmlAttribute class is equipped with a property named Value. Besides Value, to support the text of an attribute, the XmlAttribute provides a property named InnerText.

The Inner XML of an Attribute

To give you access to the XML of an attribute, the XmlAttribute class is equipped with a property named InnerXml.

Creating an XML Attribute

Manually Creating an Attribute

Imagine you have an ISBN element as a child of a video element as follows:

<video>
  <ISBN>0-7888-1623-3</ISBN>
</video>

An attribute must be created inside the start-tag of an element. To manually create an attribute, type the left angle bracket of the element, followed by the name of the element, an empty space, and the name of the attribute. The name follows the same rules we defined for names in XML.

An attribute should have a value that can be used to distinguish it. To specify the name of an attribute, assign a value as a string to its name. In the case of the above code, since ISBN is simply a child of the video element, you can change the ISBN element to become an attribute of the video element as follows:

<video ISBN="0-7888-1623-3">

Now, ISBN is an attribute of the video element. If you are writing code, in the start tag of the desired element, specify the desired attribute and assign a single quoted value to it.

ApplicationPractical Learning: Manually Creating an Attribute

  1. Click the BusinessController.cs tab to activate it
  2. Change the SaveCustomerOrder() method as follows:
    using System;
    using System.IO;
    using System.Xml;
    using System.Web.Mvc;
    using System.Collections.Generic;
    
    namespace ChairExecs1.Controllers
    {
        public enum Executive
        {
            Excelsior,
            Famous
        }
    
        public class BusinessController : Controller
        {
            // GET: Business
            public ActionResult Index()
            {
                return View();
            }
    
            // GET: Business/StartCustomerOrder
            public ActionResult StartCustomerOrder()
            {
                List<SelectListItem> execs = new List<SelectListItem>();
    
                execs.Add(new SelectListItem() { Text = "Excel Extent", Value = "Excel Extent" });
                execs.Add(new SelectListItem() { Text = "Executive", Value = "Executive" });
    
                ViewData["Type3Name"] = execs;
    
                return View();
            }
    
            // GET: Business/PrepareCustomerOrder
            public ActionResult PrepareCustomerOrder(string Type1Name, string Type1UnitWeight, string Type1UnitPrice, string Type1Quantity,
                                                     string Type2Name, string Type2UnitWeight, string Type2UnitPrice, string Type2Quantity,
                                                     string Type3Name, string Type3UnitWeight, string Type3UnitPrice, string Type3Quantity)
            {
                . . . No Change
    
                return View();
            }
    
            // GET: Business/SaveCustomerOrder
            public ActionResult SaveCustomerOrder(string ReceiptNumber,
                                                  string Type1Name, string Type1UnitWeight, string Type1UnitPrice, string Type1Quantity, string Type1TotalWeight, string Type1SubTotal,
                                                  string Type2Name, string Type2UnitWeight, string Type2UnitPrice, string Type2Quantity, string Type2TotalWeight, string Type2SubTotal,
                                                  string Type3Name, string Type3UnitWeight, string Type3UnitPrice, string Type3Quantity, string Type3TotalWeight, string Type3SubTotal,
                                                  string TotalWeight, string SubTotal, string DiscountRate, string DiscountAmount, string ShippingAndHandling, string OrderTotal)
            {
                FileStream fsCustomersOrders = null;
                XmlDocument xdCustomersOrders = new XmlDocument();
                string customersOrders = Server.MapPath("~/App_Data/CustomersOrders.xml");
    
                if (!string.IsNullOrEmpty(ReceiptNumber))
                {
                    int iType1Quantity = int.Parse(Request["Type1Quantity"]);
                    int iType2Quantity = int.Parse(Request["Type2Quantity"]);
                    int iType3Quantity = int.Parse(Request["Type3Quantity"]);
    
                    if (System.IO.File.Exists(customersOrders))
                    {
                        using (fsCustomersOrders = new FileStream(customersOrders, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            xdCustomersOrders.Load(fsCustomersOrders);
                        }
                    }
                    else
                    {
                        xdCustomersOrders.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                                                  "<customers-orders></customers-orders>");
                    }
    
                    XmlElement xeCustomerOrder = xdCustomersOrders.CreateElement("customer-order");
    
                    string strCharacteristics = string.Empty;
                    string strCustomerOrder = "<receipt-number>" + ReceiptNumber + "</receipt-number>";
    
                    if(Type1Name == Models.Basic.Essential.ToString())
                    {
                        strCharacteristics = "<type1-name length='25.6' width='34.65' height='41.36' max-weight-capcity='225'>" + Type1Name + "</type1-name>";
                    }
                    else if (Type1Name == Models.Basic.Instructor.ToString())
                    {
                        strCharacteristics = "<type1-name depth='24.76' width='35.27' height='39.42' max-weight-capcity='232'>" + Type1Name + "</type1-name>";
                    }
                    else // if (Type1Name == Models.Basic.Station.ToString())
                    {
                        strCharacteristics = "<type1-name>" + Type1Name + "</type1-name>";
                    }
    
                    strCustomerOrder += strCharacteristics;
    
                    if(iType1Quantity > 0)
                    {
                        strCharacteristics = "<type1-unit-weight kilograms='" + (float.Parse(Type1UnitWeight) * 0.453592).ToString("F") + "'>" + Type1UnitWeight + "</type1-unit-weight>";
                    }
                    else // if(iType1Quantity > 0)
                    {
                        strCharacteristics = "<type1-unit-weight>" + Type1UnitWeight + "</type1-unit-weight>";
                    }
    
                    strCustomerOrder += strCharacteristics +
                                        "<type1-unit-price>" + Type1UnitPrice + "</type1-unit-price>" +
                                        "<type1-quantity>" + Type1Quantity + "</type1-quantity>";
    
                    if (iType1Quantity > 0)
                    {
                        strCharacteristics = "<type1-total-weight kilograms='" + (float.Parse(Type1TotalWeight) * 0.453592).ToString("F") + "'>" + Type1TotalWeight + "</type1-total-weight>";
                    }
                    else // if(iType1Quantity > 0)
                    {
                        strCharacteristics = "<type1-total-weight>" + Type1TotalWeight + "</type1-total-weight>";
                    }
    
                    strCustomerOrder += strCharacteristics + "<type2-sub-total>" + Type2SubTotal + "</type2-sub-total>";
    
                    if (Type2Name == "Conviction")
                    {
                        strCharacteristics = "<type2-name depth='28.54' width='39.18' height='42.73' max-weight-capcity='362'>" + Type2Name + "</type2-name>";
                    }
                    else // if (Type2Name == "Scholar")
                    {
                        strCharacteristics = "<type2-name length='26.18' width='28.52' height='45.04' max-weight-capcity='320'>" + Type2Name + "</type2-name>";
                    }
    
                    strCustomerOrder += strCharacteristics;
    
                    if (iType2Quantity > 0)
                    {
                        strCharacteristics = "<type2-unit-weight kilograms='" + (float.Parse(Type2UnitWeight) * 0.453592).ToString("F") + "'>" + Type2UnitWeight + "</type2-unit-weight>";
                    }
                    else // if(iType2Quantity > 0)
                    {
                        strCharacteristics = "<type2-unit-weight>" + Type2UnitWeight + "</type2-unit-weight>";
                    }
    
                    strCustomerOrder += strCharacteristics +
                                        "<type2-unit-price>" + Type2UnitPrice + "</type2-unit-price>" +
                                        "<type2-quantity>" + Type2Quantity + "</type2-quantity>";
    
                    if (iType2Quantity > 0)
                    {
                        strCharacteristics = "<type2-total-weight kilograms='" + (float.Parse(Type2TotalWeight) * 0.453592).ToString("F") + "'>" + Type2TotalWeight + "</type2-total-weight>";
                    }
                    else // if(iType2Quantity > 0)
                    {
                        strCharacteristics = "<type2-total-weight>" + Type2TotalWeight + "</type2-total-weight>";
                    }
    
                    strCustomerOrder += strCharacteristics + "<type2-sub-total>" + Type2SubTotal + "</type2-sub-total>";
    
                    if (Type3Name == "Excel Extent")
                    {
                        strCharacteristics = "<type3-name depth='34.26' width='32.24' height='26.84' max-weight-capcity='565'>" + Type3Name + "</type3-name>";
                    }
                    else // if (Type2Name == "Executive")
                    {
                        strCharacteristics = "<type3-name length='32.08' width='29.94' height='37.62' max-weight-capcity='450'>" + Type3Name + "</type3-name>";
                    }
    
                    strCustomerOrder += strCharacteristics;
    
                    if (iType3Quantity > 0)
                    {
                        strCharacteristics = "<type3-unit-weight kilograms='" + (float.Parse(Type3UnitWeight) * 0.453592).ToString("F") + "'>" + Type3UnitWeight + "</type3-unit-weight>";
                    }
                    else // if(iType3Quantity > 0)
                    {
                        strCharacteristics = "<type3-unit-weight>" + Type3UnitWeight + "</type3-unit-weight>";
                    }
    
                    strCustomerOrder += strCharacteristics +
                                        "<type3-unit-price>" + Type3UnitPrice + "</type3-unit-price>" +
                                        "<type3-quantity>" + Type3Quantity + "</type3-quantity>";
    
                    if (iType3Quantity > 0)
                    {
                        strCharacteristics = "<type3-total-weight kilograms='" + (float.Parse(Type3TotalWeight) * 0.453592).ToString("F") + "'>" + Type3TotalWeight + "</type3-total-weight>";
                    }
                    else // if(iType3Quantity > 0)
                    {
                        strCharacteristics = "<type3-total-weight>" + Type3TotalWeight + "</type3-total-weight>";
                    }
    
                    strCustomerOrder += strCharacteristics +
                                        "<type3-sub-total>" + Type3SubTotal + "</type3-sub-total>" +
                                        "<total-weight>" + TotalWeight + "</total-weight>" +
                                        "<sub-total>" + SubTotal + "</sub-total>" +
    
                                        "<discount rate='" + DiscountRate + "'>" + DiscountAmount + "</discount>" +
                                        "<shipping-and-handling>" + ShippingAndHandling + "</shipping-and-handling>" +
                                        "<order-total>" + OrderTotal + "</order-total>";
    
                    xeCustomerOrder.InnerXml = strCustomerOrder;
    
                    xdCustomersOrders.DocumentElement.AppendChild(xeCustomerOrder);
    
                    using (fsCustomersOrders = new FileStream(customersOrders, FileMode.Create, FileAccess.Write, FileShare.Write))
                    {
                        xdCustomersOrders.Save(fsCustomersOrders);
                    }
    
                }
    
                return RedirectToAction("StartCustomerOrder");
            }
        }
    }
  3. Click the StartCustomerOrder.cshtml tab to access it
  4. To execute the project, on the main menu, click Debug ->Start Without Debugging
  5. In the first row, set the quantity to 1
  6. For the second combo box, select Conviction and set the values as follows:
    Weight:      48
    Unit Price:  125.25
    Quantity:    4
  7. For the 3rd combo box, select Executive set the corresponding values as follows:
    Weight:     58
    Unit Price: 238.75
    Quantity:   3

    Viewing Data in a View

  8. Click the Prepare Customer Order button:

    Introducing Interfaces

  9. Set the values as follows:

    Item Name Weight Unit Price Quantiry
    Instructor 35 48.50 7
    Excel Extent 52 207.75 2
  10. Click the Prepare Customer Order button:

    Introducing Interfaces

  11. Click the Save Customer Order button:
    <?xml version="1.0" encoding="utf-8"?>
    <customers-orders>
      <customer-order>
        <receipt-number>100001</receipt-number>
        <type1-name>Station</type1-name>
        <type1-unit-weight kilograms="12.70">28</type1-unit-weight>
        <type1-unit-price>64.95</type1-unit-price>
        <type1-quantity>1</type1-quantity>
        <type1-total-weight kilograms="12.70">28</type1-total-weight>
        <type2-sub-total>501.00</type2-sub-total>
        <type2-name length="26.18" width="28.52" height="45.04" max-weight-capcity="320">Scholar</type2-name>
        <type2-unit-weight kilograms="21.77">48</type2-unit-weight>
        <type2-unit-price>125.25</type2-unit-price>
        <type2-quantity>4</type2-quantity>
        <type2-total-weight kilograms="87.09">192</type2-total-weight>
        <type2-sub-total>501.00</type2-sub-total>
        <type3-name length="32.08" width="29.94" height="37.62" max-weight-capcity="450">Executive</type3-name>
        <type3-unit-weight kilograms="26.31">58</type3-unit-weight>
        <type3-unit-price>238.75</type3-unit-price>
        <type3-quantity>3</type3-quantity>
        <type3-total-weight kilograms="78.93">174</type3-total-weight>
        <type3-sub-total>716.25</type3-sub-total>
        <total-weight>134</total-weight>
        <sub-total>1282.20</sub-total>
        <discount rate="20.00">256.44</discount>
        <shipping-and-handling>24.48</shipping-and-handling>
        <order-total>1050.24</order-total>
      </customer-order>
      <customer-order>
        <receipt-number>100002</receipt-number>
        <type1-name depth="24.76" width="35.27" height="39.42" max-weight-capcity="232">Instructor</type1-name>
        <type1-unit-weight kilograms="15.88">35</type1-unit-weight>
        <type1-unit-price>48.50</type1-unit-price>
        <type1-quantity>7</type1-quantity>
        <type1-total-weight kilograms="111.13">245</type1-total-weight>
        <type2-sub-total>0.00</type2-sub-total>
        <type2-name length="26.18" width="28.52" height="45.04" max-weight-capcity="320">Scholar</type2-name>
        <type2-unit-weight>36</type2-unit-weight>
        <type2-unit-price>104.45</type2-unit-price>
        <type2-quantity>0</type2-quantity>
        <type2-total-weight>0</type2-total-weight>
        <type2-sub-total>0.00</type2-sub-total>
        <type3-name depth="34.26" width="32.24" height="26.84" max-weight-capcity="565">Excel Extent</type3-name>
        <type3-unit-weight kilograms="23.59">52</type3-unit-weight>
        <type3-unit-price>207.75</type3-unit-price>
        <type3-quantity>2</type3-quantity>
        <type3-total-weight kilograms="47.17">104</type3-total-weight>
        <type3-sub-total>415.50</type3-sub-total>
        <total-weight>123</total-weight>
        <sub-total>755.00</sub-total>
        <discount rate="15.00">113.25</discount>
        <shipping-and-handling>24.48</shipping-and-handling>
        <order-total>666.23</order-total>
      </customer-order>
    </customers-orders>
  12. Close the browser and return to your programming environment

Adding an Attribute to an Element

As mentioned already, an attribute primarily belongs to an element. This means that, when creating an attribute, you must specify what element it would belong to. To support the attributes of an element, the XmlElement class is equipped with a method named SetAttribute. It is overloaded in two versions. The first version of this method uses the following syntax:

public virtual void SetAttribute(string name, string value);

The first argument is the name of the new attribute and the second argument will be its text. Consider an XML file named Employees.xml as follows:

<?xml version="1.0" encoding="utf-8" ?>
<employees>
  <employee>
    <employee-number>283947</employee-number>
    <first-name>Frank</first-name>
    <last-name>Euler</last-name>
    <hourly-salary>18.25</hourly-salary>
  </employee>
</employees>

To add an attribute to an element, create an XmlElement object and call the above method on it. Here is an example:

<!DOCTYPE html>
<html>
<head>
<title>Employee Record</title>
</head>
<body>
<h2>Employee Record</h2>

@{
    string strEmployeesFile = Server.MapPath("~/App_Data/Employees.xml");
    System.Xml.XmlDocument xdEmployees = new System.Xml.XmlDocument();

    xdEmployees.Load(strEmployeesFile);

    System.Xml.XmlElement xeEmployee = xdEmployees.CreateElement("employee");

    xeEmployee.InnerXml = "<employee-number>608504</employee-number>" +
                          "<first-name>Jeannette</first-name>" +
                          "<last-name>Ngo Koum</last-name>" +
                          "<hourly-salary>22.50</hourly-salary>";

    xdEmployees.DocumentElement.AppendChild(xeEmployee);

    xeEmployee.SetAttribute("status", "Full-Time");
    xdEmployees.Save(strEmployeesFile);
}
</body>
</html>

This would produce:

<?xml version="1.0" encoding="utf-8"?>
<employees>
  <employee>
    <employee-number>283947</employee-number>
    <first-name>Frank</first-name>
    <last-name>Euler</last-name>
    <hourly-salary>18.25</hourly-salary>
  </employee>
  <employee status="Full-Time">
    <employee-number>608504</employee-number>
    <first-name>Jeannette</first-name>
    <last-name>Ngo Koum</last-name>
    <hourly-salary>22.50</hourly-salary>
  </employee>
</employees>

Add an Attribute to the Root

To add an attribute to the root node, call the SetAttribute() method on it. Here is an example:

@{
    string strVideosFile = Server.MapPath("~/App_Data/Videos.xml");
    System.Xml.XmlDocument xdVideos = new System.Xml.XmlDocument();

    if (File.Exists(strVideosFile))
    {
        // Open the XML file
        xdVideos.Load(strVideosFile);

        // Create an attribute and add it to the root element
        xdVideos.DocumentElement.SetAttribute("FileDesc",
                                              "Personal Video Collection");
        xdVideos.Save(strVideosFile);
    }
}

From the above videos.xml file, this code would result in:

<?xml version="1.0" encoding="utf-8"?>
<videos FileDesc="Personal Video Collection">
  <video ISBN="0-7888-1623-3">
    <title Screenplay="Marty Kaplan">The Distinguished Gentleman</title>
    <director>Jonathan Lynn</director>
    <length>112 Minutes</length>
    <format>DVD</format>
    <rating>R</rating>
  </video>
  <video>
    <title WrittenBy="Charlie Peter">Her Alibi</title>
    <director>Bruce Beresford</director>
    <length>94 Mins</length>
    <format>DVD</format>
    <rating>PG-13</rating>
  </video>
</videos>

Adding an Attribute to an Existing Element

To support attribute addition, the XmlDocument class is equipped with a method named CreateAttribute. It is overloaded with three versions. The first version of this method has the following syntax:

public XmlAttribute CreateAttribute(string name);

This method expects the name of the attribute as argument. If it succeeds, this method produces an XmlAttribute object. To let you add the new attribute to an element, the XmlElement class is equipped with a method named SetAttributeNode method. This method is overloaded in two versions. One of the versions uses the following syntax:

public virtual XmlAttribute SetAttributeNode(XmlAttribute newAttr);

This method expects an XmlAttribute object. Here is an example that looks for a particular video in a collection and adds an ISBN attribute to it:

@{
    string strVideosFile = Server.MapPath("~/App_Data/Videos.xml");
    System.Xml.XmlDocument xdVideos = new System.Xml.XmlDocument();

    if (File.Exists(strVideosFile))
    {
        // Open the XML file
        xdVideos.Load(strVideosFile);

        // Create a new attribute
        System.Xml.XmlAttribute xaVideo = xdVideos.CreateAttribute("ISBN");
        xaVideo.Value = "0-7907-3900-3";

        // Get a list of elements whose names are Video
        System.Xml.XmlNodeList xnlVideos = xdVideos.GetElementsByTagName("video");
        // Since we will look for a specific video, get the list of all titles
        System.Xml.XmlNodeList xnlTitles = xdVideos.GetElementsByTagName("title");

        // Visit each title
        for (int i = 0; i < xnlTitles.Count; i++)
        {
            // Look for a video whose title is "Her Alibi"
            if (xnlTitles[i].InnerText.Equals("Her Alibi"))
            {
                // Once you find that video, add the new attribute to it
                ((System.Xml.XmlElement)(xnlVideos[i])).SetAttributeNode(xaVideo);
            }
        }

        xdVideos.Save(strVideosFile);
    }
}

From the above Videos.xml file, this code would result in:

<?xml version="1.0" encoding="utf-8"?>
<videos FileDesc="Personal Video Collection">
  <video ISBN="0-7888-1623-3">
    <title Screenplay="Marty Kaplan">The Distinguished Gentleman</title>
    <director>Jonathan Lynn</director>
    <actors>
    </actors>
    <length>112 Minutes</length>
    <format>DVD</format>
    <rating>R</rating>
  </video>
  <video ISBN="0-7907-3900-3">
    <title WrittenBy="Charlie Peter">Her Alibi</title>
    <director>Bruce Beresford</director>
    <length>94 Mins</length>
    <format>DVD</format>
    <rating>PG-13</rating>
  </video>
</videos>

The Parent of an Attribute

Once an attribute has been created, to identify the element it belongs to, you can access its XmlAttribute.OwnerElement property. This property produces an XmlElement value.

Attribute Removal

If an element has an attribute you don't want or that you don't need anymore, you can delete that attribute. You have various options, two are available through the XmlElement class.

The attributes of an XmlElement object are considered stored in an indexed list with the most left attribute at index 0, the second from left at index 1, and so on. Based on this, to remove an attribute by locating it based on its index, you can call the XmlElement.RemoveAttributeAt() method. Its syntax is:

public virtual XmlNode RemoveAttributeAt(int i);

When calling this method, if an attribute exists at position i, it will be deleted and the method would return it. If there is no attribute at that index, the method doesn't do anything and it returns 0.

Using the XmlElement.RemoveAttributeAt() method to delete an attribute can be uncertain because you would not know whether there is an attribute at the specified position. An alternative is to specify the name of the attribute you want to delete. To support this, the XmlElement class is equipped with the RemoveAttribute() method, which is overloaded with two versions. One of the versions of this method uses the following syntax:

public virtual void RemoveAttribute(string name);

This method expects as argument the name of the attribute to remove.

Another technique you can use consists of defining an XmlAttribute object and submitting to its XmlElement parent to delete. To do this, you can call the RemoveAttributeNode() method of the XmlElement object. Its syntax is:

public virtual XmlAttribute RemoveAttributeNode(XmlAttribute oldAttr);

When calling this method, pass the attribute object as argument. If the attribute exists, it would be removed and the method would return the deleted attribute. If the attribute doesn't exist, nothing would happen.

The Collection of Attributes of an Element

Introduction

So far, we have used only one attribute per element. Fortunately, you can create as many attributes as you judge necessary in an element. To do this, type the name of each attribute, assign it a double-quoted string and separate the attribute from the next with an empty space. Here is an example of an element with different attributes:

<video ISBN="0-7888-1623-3" ScreenRatio="Standard" SoundtrackAvailable="True" />

As mentioned already and as you should always remember, attributes belong to an element. To support them, the attributes of an element are stored in the Attributes property of the XmlElement class. The XmlElement.Attributes property is based on a class called XmlAttributeCollection.

To know the number of attributes in an element, you can use the XmlNamedNodeMap.Count property.

Attribute Addition

Whether using its index or name, after accessing an attribute, you can manipulate it as you see fit. For example, you can change or delete it using the same techniques we saw to perform on an individual attribute.

As mentioned already, the attributes are stored as a list. Because you have complete access to this list and the positions of its attributes, when creating or adding a new attribute, you can specify the position the new attribute should have in the collection. To create an attribute as the first in an element, you can call the XmlAttributeCollection.Prepend() method. Its syntax is:

public virtual XmlAttribute Prepend(XmlAttribute node);

Another technique you can use consists of locating an attribute first. Once you have one, to create a new attribute before it, you can call the XmlAttributeCollection.InsertBefore() method. Its syntax is:

public virtual XmlAttribute InsertBefore(XmlAttribute newNode,
					 XmlAttribute refNode);

To add a new attribute after the current one, you can call the XmlAttributeCollection.InsertAfter() method. Its syntax is:

public virtual XmlAttribute InsertAfter(XmlAttribute newNode,
					XmlAttribute refNode);

To add an attribute at the end of the list of attributes of an element, you can call the XmlAttributeCollection.Append() method. Its syntax is:

public virtual XmlAttribute Append(XmlAttribute node); 

Access to an XML Attribute

To access an attribute by its position in the collection, you can use the XmlNamedNodeMap.Item() method.

The XmlAttributeCollection class is equipped with an ItemOf indexed property. This property is overloaded in three versions. The first version has the following syntax:

public virtual XmlAttribute this[int i] {get;}

This property allows you to access an attribute by considering that the attributes are stored in an array. The first or most left attribute has an index of 0; the second attribute from left (of course without counting the name of the element) has an index of 1, and so on.

It can be difficult and sometimes unpredictable, in some scenarios, to access an attribute by its index because you must know exactly where each attribute is positioned. Consider the following version of our Videos.xml XML file:

<?xml version="1.0" encoding="utf-8" ?>
<videos FileDesc="Personal Video Collection">
    <video ISBN="0-7888-1623-3"
	   ScreenRatio="Standard"
	   SoundtrackAvailable="True">
        <title StoryBy="Marty Kaplan and Jonathan Reynold"
	       Screenplay="Marty Kaplan">The Distinguished Gentleman</title>
        <director>Jonathan Lynn</director>
        <actors></actors>
        <length>112 Minutes</length>
        <format>DVD</format>
        <rating>R</rating>
    </video>
    <video ISBN="0-7907-3900-3">
        <title Screenplay="Charlie Peter">Her Alibi</title>
        <director>Bruce Beresford</director>
        <length>94 Mins</length>
        <format>DVD</format>
        <rating>PG-13</rating>
    </video>
</videos>

In the first video, the name of the screenplay writer is stored at index 1. In the second video, the name of the screenplay writer is stored at index 0. In this case, it may not be a good item to use the index to locate an attribute. Fortunately, the second version of the overloaded XmlAttributeCollection.ItemOf[] property has the following syntax:

public virtual XmlAttribute this[string name] {get;}

With this version, you can explicitly specify the name of the attribute that you want.

Attribute Removal

Using the list of attributes of an element, you can delete one or all attributes of an element. Since the attributes are stored in a collection, you can locate the undesired attribute by its index and then delete it. To do this, you can call the XmlAttributeCollection.RemoveAt() method. Its syntax is:

public virtual XmlAttribute RemoveAt(int i);

This method expects the index of the attribute that needs to be removed. As mentioned for the XmlAttributeCollection.ItemOf indexed property, to efficiently use this RemoveAt() method, you should know the exact index of the attribute, otherwise, you may access and therefore delete the wrong attribute. An alternative is to explicitly identify the attribute you want to delete. To do this, you can call the XmlAttributeCollection.Remove() method. Its syntax is:

public virtual XmlAttribute Remove(XmlAttribute node);

This method takes as attribute the XmlAttribute identification of the attribute you want to remove.

To delete all attributes of an element, you can call the XmlAttributeCollection.RemoveAll() method. Its syntax is:

public virtual void RemoveAll();

This method would simply remove all attributes that belong to an XmlElement object.

Overview of Types of Nodes

Introduction

To differentiate the various nodes that belong to an XML file, they are classified by their category. As mentioned earlier, the types of node are listed in the XmlNodeType enumerator.

Comments

A comment is a character, a line or a paragraph that is not considered as part of the XML code that needs to be processed. A comment allows you to insert notes or personal observations inside an XML file. For this reason, a commented section can be written any way you like. This means that a comment can include plain text, formulas, expressions, or even XML code as long as you know that that XML code will not be validated: it will ignored by the parser.

To create a comment, you use the following formula:

<!-- Blah Blah Blah ->

Between <!-- and -->, any text in that section is considered a comment and you can include anything you want. Both sections of the comment use two dashes, not more, not less. Here is an example:

<?xml version="1.0" encoding="utf-8"?>
<!-- In this collection, we will keep each title "as is" -->
<videos>
  <video>
	<title>The Distinguished Gentleman</title>
	<director>Jonathan Lynn</director>
	<length>112 Minutes</length>
	<format>DVD</format>
	<rating>R</rating>
  </video>
  <video>
	<title>Her Alibi</title>
	<director>Bruce Beresford</director>
	<length>94 Mins</length>
	<format>DVD</format>
	<rating>PG-13</rating>
  </video>
</videos>

The System.Xml represents a comment through the XmlComment class. Like any other part of an XML file, a comment is represented by the XmlComment.Name property. This allows you to retrieve the name of a comment that is included in the document.

To create a comment, you can call the XmlDocument.CreateComment() method. Its syntax is:

public virtual XmlComment CreateComment(string data);

This method takes as argument the text that would go into the commented section. After calling it, if the method succeeds, which it usually does, it returns the XmlComment object that was created.

CDATA

Except for comments, the parser is used to "scan" the whole XML file to analyze it. Every tag is then interpreted. As we mentioned already, the value of each tag can be displayed in a browser between its opening and its closing tag, and the browser uses different font styles to make a distinction. When creating some tags and some sections of the file, you may want the parser to consider those particular tags and sections as regular text. That is, you may want the parser to treat a certain tag and its value as if it were regular text even though it is created as an XML file.

To prevent the parser from interpreting a tag regularly but to treat that tag and its value as regular text, you can create it in a CDATA section. To do this, create a section that starts with <![CDATA[, followed by anything you want, and ending with ]]>. The formula used is:

<![CDATA[ Blah Blah Blah ]]>

Between <![CDATA[ and ]]>, you can type anything, including one or more normal XML tags. Here is an example:

<?xml version="1.0" encoding="utf-8"?>
<!-- In this collection, we will keep each title "as is" -->
<videos>
  <![CDATA[<VdoColl>Collection of Videos</VdoColl>]]>
  <video>
	<title>The Distinguished Gentleman</title>
	<director>Jonathan Lynn</director>
	<length>112 Minutes</length>
	<format>DVD</format>
	<rating>R</rating>
  </video>
  <video>
	<title>Her Alibi</title>
	<director>Bruce Beresford</director>
	<length>94 Mins</length>
	<format>DVD</format>
	<rating>PG-13</rating>
  </video>
</videos>

The .NET Framework supports the creation of a CDATA section through the XmlCDataSection class. This class is equipped with a Name property that allows you t retrieve the name of a CDATA section in an XmlDocument object.

To programmatically create a CDATA section, you can call the XmlDocument.CreateCDataSection() method. Its syntax is:

public virtual XmlCDataSection CreateCDataSection(string data);

Practical Learning: Ending the Lesson


Previous Copyright © 2005-2018, FunctionX Next