XML Dropdown with Names and Values

2019-08-18 02:50发布

问题:

I have three dependent, cascading dropdown lists. They are populated from an XML file, which works fine for the list items, but I need the values included in the list items so I can pass them to the DB.

Here is one node from my restructured XML document:

    <Organizations>
  <Organization>
    <name value="A0EAD6A8813E474B9F9A3E0C64D72F61">Hospital</name>
    <JobTitle1>
      <name value="-2">Physician</name>
      <JobTitle2>
        <name value="E5B838C3AA304813B3EA4E28EE33702F">Anesthesiologist</name>
       </JobTitle2>
      <JobTitle2>
        <name value="36C9F22DC54347CEA39C142FE91E8B36">A and E</name>
       </JobTitle2>
      <JobTitle2>
        <name value="35E798C18DC04ECFB022DCF0E6DBEB51">Cardiologist</name>
       </JobTitle2>
      <JobTitle2>
        <name value="343B2555E45142E096546A3781680C02">Dental Surgeon</name>
       </JobTitle2>
      <JobTitle2>
        <name value="A5C669F6DB4D41DA8409960D6952023C">Diabetologist/Endocrinologist</name>
       </JobTitle2>
      <JobTitle2>
        <name value="2B01B4C29253459797CB596FE81C3AF4">ENT</name>
       </JobTitle2>
      <JobTitle2>
        <name value="6C761F3F81CB421BBD0746914031EF19">General Medicine</name>
       </JobTitle2>
      <JobTitle2>
        <name value="9DB49A58B8484E73AA24227DCDAD4C96">Intensivist</name>
       </JobTitle2>
      <JobTitle2>
        <name value="F80D023B174A421A82A140691BCD9E22">Neurologist</name>
       </JobTitle2>
      <JobTitle2>
        <name value="3F95529E15764EB1A55255DCEDDB6C4A">Pediatrician</name>
       </JobTitle2>
      <JobTitle2>
        <name value="9FC573D63A884C04A8675E86B43EABB9">Psychiatrist</name>
       </JobTitle2>
      <JobTitle2>
        <name value="7230D95FE4844A7785D25A73D5240BB9">Respiratory</name>
       </JobTitle2>
      <JobTitle2>
        <name value="E784A9F594BF468D85C51BBD5A9B0F5D">Trainee</name>
       </JobTitle2>
      <JobTitle2>
        <name value="431614E6148A4F639F912ED08803BD79">Other Physician</name>
       </JobTitle2>
    </JobTitle1>
    <JobTitle1>
      <name value="111AEF6C39984713AA10E6F1D051F97E">Nurse</name>
    </JobTitle1>
    <JobTitle1>
      <name value="90CF5DB3D06A4B759F21A3F20B5F5DD4">Physiologist</name>
    </JobTitle1>
    <JobTitle1>
      <name value="55F8C6537718420DB6E4E3A7C087D540">Physiotherapist</name>
     </JobTitle1>
    <JobTitle1>
      <name value="884EB090E9B7469DA3CA8BA2D6FC4F4E">Biomedical Engineer/Technician</name>
     </JobTitle1>
    <JobTitle1>
      <name value="C2383AA850534CD9A4E03019386AA56C">Administrator</name>
     </JobTitle1>
    <JobTitle1>
      <name value="C8997E78569A4410956E5E7C6C1D57F2">Manager</name>
     </JobTitle1>
    <JobTitle1>
      <name value="5196E883DF614A319A3CDF4573C3E858">Supplies/Procurement</name>
     </JobTitle1>
  </Organization>

The other nodes are similar, no need to waste the space to post them here. All the Text in the DDLs is working fine.

Here is aspx.cs code behind to get the values for the DDLs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;

namespace CSASPNETCascadingDropDownList
{
    public partial class CascadingDropDownListWithPostBack : System.Web.UI.Page
    {
        /// <summary>
        /// Page Load event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                // Bind Org dropdownlist
                BindddlOrg();
                ddlJobTitle1.Enabled = false;
                ddlJobTitle2.Enabled = false;

                // Insert one item to dropdownlist top
                ddlJobTitle1.Items.Insert(0, new ListItem("Select JobTitle1", "-1"));
                ddlJobTitle2.Items.Insert(0, new ListItem("Select JobTitle2", "-1"));

                // Initialize JobTitle2 dropdownlist selected index
                hdfDdlJobTitle2SelectedIndex.Value = "0";
            }
        }

        /// <summary>
        /// Bind Org dropdownlist
        /// </summary>
        /// 
            public class XmlValue {
            public int value {get; set;} //getter and setter are important
            public string name {get; set;}
        }
        public void BindddlOrg()
        {
            List<XmlValue> list = RetrieveDataFromXml.GetAllOrg();
            ddlOrg.DataSource = list;
            ddlOrg.DataBind();
            ddlOrg.Items.Insert(0, new ListItem("Select Organization", "-1"));
        }

        /// <summary>
        /// Show selected value
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Button1_Click(object sender, EventArgs e)
        {
            // Get the selected index of JobTitle2 dropdownlist
            int iJobTitle2Selected = Convert.ToInt16(hdfDdlJobTitle2SelectedIndex.Value);

            // The result will be showing
            string strResult = string.Empty;
            if (ddlOrg.SelectedIndex == 0)
            {
                strResult = "Please select a Org.";
            }
            else if (ddlJobTitle1.SelectedIndex == 0 && strResult == string.Empty)
            {
                strResult = "Please select a JobTitle1";
            }
            else if (hdfDdlJobTitle2SelectedIndex.Value == "0" && strResult == string.Empty)
            {
                strResult = "Please select a JobTitle2.";
            }
            else
            {
                strResult = "You selected Org: " + ddlOrg.SelectedValue
                    + " ; JobTitle1: " + ddlJobTitle1.SelectedValue
                    + " ; JobTitle2: " + ddlJobTitle2.Items[iJobTitle2Selected].Value;
            }

            LabelResult.Text = strResult;
        }


        /// <summary>
        /// Org dropdownlist SelectedIndexChanged event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void ddlOrg_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Remove JobTitle1 dropdownlist items
            ddlJobTitle1.Items.Clear();
            string strOrg = string.Empty;
            strOrg = ddlOrg.SelectedValue;
            List<string> list = null;

            // Bind JobTitle1 dropdownlist based on Org value
            if (ddlOrg.SelectedIndex != 0)
            {
                list = RetrieveDataFromXml.GetJobTitle1ByOrg(strOrg);
                if (list != null && list.Count != 0)
                {
                    ddlJobTitle1.Enabled = true;
                }

                ddlJobTitle1.DataSource = list;
                ddlJobTitle1.DataBind();
            }
            else
            {
                ddlJobTitle1.Enabled = false;
            }

            ddlJobTitle1.Items.Insert(0, new ListItem("Select JobTitle12", "-1"));

            // Clear JobTitle2 dropdownlist
            ddlJobTitle2.Enabled = false;
            ddlJobTitle2.Items.Clear();
            ddlJobTitle2.Items.Insert(0, new ListItem("Select JobTitle22", "-1"));

            // Initialize JobTitle2 dropdownlist selected index
            hdfDdlJobTitle2SelectedIndex.Value = "0";
        }


        /// <summary>
        /// JobTitle1 dropdownlist SelectedIndexChanged event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void ddlJobTitle1_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Bind JobTitle2 dropdownlist based on JobTitle1 value
            string strJobTitle1 = string.Empty;
            strJobTitle1 = ddlJobTitle1.SelectedValue;
            List<string> list = null;
            list = RetrieveDataFromXml.GetJobTitle2ByJobTitle1(strJobTitle1);
            ddlJobTitle2.Items.Clear();
            ddlJobTitle2.DataSource = list;
            ddlJobTitle2.DataBind();
            ddlJobTitle2.Items.Insert(0, new ListItem("Select JobTitle2", "-1"));

            // Initialize JobTitle2 dropdownlist selected index
            hdfDdlJobTitle2SelectedIndex.Value = "0";

            // Enable JobTitle2 dropdownlist when it has items
            if (list.Count > 0)
            {
                ddlJobTitle2.Enabled = true;
            }
            else
            {
                ddlJobTitle2.Enabled = false;
            }
        }
    }
    }

Here is the cs file code to get the values from the XML:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml;

namespace CSASPNETCascadingDropDownList
{
    /// <summary>
    /// Summary description for CSRetrieveDataFromXml
    /// </summary>
    public class RetrieveDataFromXml
    {
        /// <summary>
        /// Constructor 
        /// </summary>
        public RetrieveDataFromXml()
        {
            //
            // TODO: Add constructor logic here
            //
        }


        /// <summary>
        /// Get the data source path, in this case, it is the XML file in the 
        /// App_Data folder
        /// </summary>
        private static string strXmlPath = HttpContext.Current.Server.MapPath(
            "App_Data") + "\\CustomDataSourceDeep.xml";

        /// <summary>
        /// Get all orgs
        /// </summary>
        /// <returns>The List contains organization</returns>


/* this block works */
 /*       public static List<string> GetAllOrg()
        {
            XmlDocument document = new XmlDocument();
            document.Load(strXmlPath);
            XmlNodeList nodeList = document.SelectNodes("Organizations/Organization");
            List<string> list = new List<string>();
            foreach (XmlNode node in nodeList)
            {
               list.Add(node.Attributes["name"].InnerText);
            }
            return list;
        }*/
/* end of working block */
/*
         public static List<string> GetAllOrg()
       {
           XmlDocument document = new XmlDocument();
           document.Load(strXmlPath);
           XmlNodeList nodeList = document.SelectNodes("Organizations/Organization");
           List<string> list = new List<string>();
           foreach (XmlNode node in nodeList)
           {
               list.Add(node.SelectSingleNode("name").InnerText, node.Attributes["value"].Value);
           }
           return list;
       }
*/
     public class XmlValue {
     public string value {get; set;} //getter and setter are important
     public string name {get; set;}
}
          public static List<XmlValue> GetAllOrg()
    {
        XmlDocument document = new XmlDocument();
        document.Load(strXmlPath);
        XmlNodeList nodeList = document.SelectNodes("Organizations/Organization");
        List<XmlValue > list = new List<XmlValue >();
        foreach (XmlNode node in nodeList)
        {
            list.Add(new XmlValue(){
            value = node.Attributes["name"].Value,
            name = node.InnerText
                 });
         }
    return list;
}    

        /// <summary>
        /// Get JobTitle1 based on Org
        /// </summary>
        /// <param name="strOrg">The Org name</param>
        /// <returns>The list contains JobTitle1</returns>
        public static List<string> GetJobTitle1ByOrg(string strOrg)
        {
            XmlDocument document = new XmlDocument();
            document.Load(strXmlPath);
            XmlNodeList nodeList = document.SelectNodes(
                "Organizations/Organization[@name='" + strOrg + "']/JobTitle1");
            List<string> list = new List<string>();
            foreach (XmlNode node in nodeList)
            {
                list.Add(node.Attributes["name"].Value);
            }

            return list;
        }


        /// <summary>
        ///  Get JobTitle2 based on JobTitle1
        /// </summary>
        /// <param name="strJobTitle1">The JobTitle1 name</param>
        /// <returns>The list contains JobTitle2</returns>
        public static List<string> GetJobTitle2ByJobTitle1(string strJobTitle1)
        {
            XmlDocument document = new XmlDocument();
            document.Load(strXmlPath);
            XmlNodeList nodeList = document.SelectNodes(
                "Organizations/Organization/JobTitle1[@name='" + strJobTitle1 + "']/JobTitle2");
            List<string> list = new List<string>();
            foreach (XmlNode node in nodeList)
            {
                list.Add(node.Attributes["name"].Value);
            }
            return list;
        }
    }
}

Here's the source that is generated for the first DDL:

<option value="-1">Select Org</option>
<option selected="selected" value="Hospital">Hospital</option>
<option value="Sleep Lab">Sleep Lab</option>
<option value="Ventilation Home Service">Ventilation Home Service</option>
<option value="Community Health Centre">Community Health Centre</option>
<option value="Home Care Provider">Home Care Provider</option>
<option value="Med">Med</option>
<option value="Other">Other</option>

What I need is this:

<option value="-1">Select Org</option>
<option selected="selected" value="A0EAD6A8813E474B9F9A3E0C64D72F61">Hospital</option>
<option value="DD8BE886FA18401E9CF30AC64B49ACD8">Sleep Lab</option>
<option value="F8182C928BE14239A576895D39591D38e">Ventilation Home Service</option>
<option value="E3865431ECF9499692E79DBF2FBAA3B2">Community Health Centre</option>
<option value="711AA0D43D6346FC9AD38659D9CB8840">Home Care Provider</option>
<option value="D54FAE898ECF4AB4A92B99C5AA536910">ResMed</option>
<option value="4E44CDB4F7E5426E99368194BBB73282">Other</option>

How do I get the DDL to continue to populate correctly yet still give me the values I need to pass to the DB?

Edited:

I'm now getting this error:

Error 1 Cannot implicitly convert type 'System.Collections.Generic.List ' to 'System.Collections.Generic.List'

回答1:

You can have an object (not sure that a map can be used as ItemSource)

    private class XmlValue {
     public int value {get; set:} //getter and setter are important
     public string name {get; set:}
}

To parse your XML :

  public static List<XmlValue> GetAllOrg()
    {
        XmlDocument document = new XmlDocument();
        document.Load(strXmlPath);
        XmlNodeList nodeList = document.SelectNodes("Organizations/Organization");
        List<XmlValue > list = new List<XmlValue >();
        foreach (XmlNode node in nodeList)
        {
            list.Add(new XmnValue(){
            value = node.Attributes["name"].Value,
            name = node.Attributes["name"].Name
                 });
         }
    return list;
}    

Your DDL :

public void BindddlOrg()
    {
        List<XmlValue > list = RetrieveDataFromXml.GetAllOrg();

        ddlOrg.ItemsSource = list;

        ddlOrg.Items.Insert(0, new XmlValue (){nqme = "Select Org", value=-1});
    }

Finally, to bind your two others ddl, use ItemSelected.

Hope it helps,