3
    <CONTAINER>
     <SHORT-NAME>ESP_DiagExtModeSts</SHORT-NAME>
     <DEFINITION-REF DEST="PARAM-CONF-CONTAINER-DEF">/AUTOSAR/Com/ComConfig/ComSignal</DEFINITION-REF>
     <PARAMETER-VALUES>
      <BOOLEAN-VALUE>
       <DEFINITION-REF DEST="BOOLEAN-PARAM-DEF">/AUTOSAR/Com/ComConfig/ComSignal/ComAliveCounter</DEFINITION-REF>
       <VALUE>false</VALUE>
      </BOOLEAN-VALUE>
      <BOOLEAN-VALUE>
       <DEFINITION-REF DEST="BOOLEAN-PARAM-DEF">/AUTOSAR/Com/ComConfig/ComSignal/ComChecksum</DEFINITION-REF>
       <VALUE>false</VALUE>
      </BOOLEAN-VALUE>
      <INTEGER-VALUE>
       <DEFINITION-REF DEST="INTEGER-PARAM-DEF">/AUTOSAR/Com/ComConfig/ComSignal/ComBitPosition</DEFINITION-REF>
       <VALUE>3</VALUE>
      </INTEGER-VALUE>
      <INTEGER-VALUE>
       <DEFINITION-REF DEST="INTEGER-PARAM-DEF">/AUTOSAR/Com/ComConfig/ComSignal/ComSignalDataInvalidValue</DEFINITION-REF>
       <VALUE>0</VALUE>
      </INTEGER-VALUE>
      <INTEGER-VALUE>
       <DEFINITION-REF DEST="INTEGER-PARAM-DEF">/AUTOSAR/Com/ComConfig/ComSignal/ComSignalInitValue</DEFINITION-REF>
       <VALUE>0</VALUE>
      </INTEGER-VALUE>
      <INTEGER-VALUE>
       <DEFINITION-REF DEST="INTEGER-PARAM-DEF">/AUTOSAR/Com/ComConfig/ComSignal/ComSignalLength</DEFINITION-REF>
       <VALUE>1</VALUE>
      </INTEGER-VALUE>
      <ENUMERATION-VALUE>
       <DEFINITION-REF DEST="ENUMERATION-PARAM-DEF">/AUTOSAR/Com/ComConfig/ComSignal/ComTransferProperty</DEFINITION-REF>
       <VALUE>PENDING</VALUE>
      </ENUMERATION-VALUE>
      <INTEGER-VALUE>
       <DEFINITION-REF DEST="INTEGER-PARAM-DEF">/AUTOSAR/Com/ComConfig/ComSignal/ComUpdateBitPosition</DEFINITION-REF>
       <VALUE>-1</VALUE>
      </INTEGER-VALUE>
      <INTEGER-VALUE>
       <DEFINITION-REF DEST="INTEGER-PARAM-DEF">/AUTOSAR/Com/ComConfig/ComSignal/ComBitSize</DEFINITION-REF>
       <VALUE>1</VALUE>
      </INTEGER-VALUE>
      <ENUMERATION-VALUE>
       <DEFINITION-REF DEST="ENUMERATION-PARAM-DEF">/AUTOSAR/Com/ComConfig/ComSignal/ComDataInvalidAction</DEFINITION-REF>
       <VALUE>REPLACE</VALUE>
      </ENUMERATION-VALUE>
      <INTEGER-VALUE>
       <DEFINITION-REF DEST="INTEGER-PARAM-DEF">/AUTOSAR/Com/ComConfig/ComSignal/ComFirstTimeoutFactor</DEFINITION-REF>
       <VALUE>50</VALUE>
      </INTEGER-VALUE>
      <INTEGER-VALUE>
       <DEFINITION-REF DEST="INTEGER-PARAM-DEF">/AUTOSAR/Com/ComConfig/ComSignal/ComHandleId</DEFINITION-REF>
       <VALUE>67</VALUE>
      </INTEGER-VALUE>
      <FUNCTION-NAME-VALUE>
       <DEFINITION-REF DEST="FUNCTION-NAME-DEF">/AUTOSAR/Com/ComConfig/ComSignal/ComNotification</DEFINITION-REF>
       <VALUE>Rte_COMCbk_ESP_DiagExtModeSts</VALUE>
      </FUNCTION-NAME-VALUE>
      <ENUMERATION-VALUE>
       <DEFINITION-REF DEST="ENUMERATION-PARAM-DEF">/AUTOSAR/Com/ComConfig/ComSignal/ComSignalEndianess</DEFINITION-REF>
       <VALUE>BIG_ENDIAN</VALUE>
      </ENUMERATION-VALUE>
      <ENUMERATION-VALUE>
       <DEFINITION-REF DEST="ENUMERATION-PARAM-DEF">/AUTOSAR/Com/ComConfig/ComSignal/ComSignalType</DEFINITION-REF>
       <VALUE>UINT8</VALUE>
      </ENUMERATION-VALUE>
      <INTEGER-VALUE>
       <DEFINITION-REF DEST="INTEGER-PARAM-DEF">/AUTOSAR/Com/ComConfig/ComSignal/ComTimeoutFactor</DEFINITION-REF>
       <VALUE>20</VALUE>
      </INTEGER-VALUE>
      <FUNCTION-NAME-VALUE>
       <DEFINITION-REF DEST="FUNCTION-NAME-DEF">/AUTOSAR/Com/ComConfig/ComSignal/ComTimeoutNotification</DEFINITION-REF>
       <VALUE>Rte_COMCbkTOut_ESP_DiagExtModeSts</VALUE>
      </FUNCTION-NAME-VALUE>
     </PARAMETER-VALUES>
     <REFERENCE-VALUES>
      <REFERENCE-VALUE>
       <DEFINITION-REF DEST="FOREIGN-REFERENCE-PARAM-DEF">/AUTOSAR/Com/ComConfig/ComSignal/SystemTemplateSystemSignalRef</DEFINITION-REF>
       <VALUE-REF DEST="I-SIGNAL-TO-I-PDU-MAPPING">/ComSignals/Pdus/msgIn_ESP_DA_Message/SG_sigESP_DiagExtSts</VALUE-REF>
      </REFERENCE-VALUE>
     </REFERENCE-VALUES>
     <SUB-CONTAINERS></SUB-CONTAINERS>
    </CONTAINER>
 private void button11_Click(object sender, EventArgs e)
    {
        XDocument doc = XDocument.Load(openFileDialog1.FileName);
        XNamespace ns = ((XElement)doc.FirstNode).Name.Namespace;

        List<XElement> containers = doc.Descendants(ns + "CONTAINER").ToList();
        foreach (XElement container in containers)
        {
            string shortName = (string)container.Element(ns + "SHORT-NAME");

            string def_ref = (string)container.Element(ns + "DEFINITION-REF").Value;

            if (shortName.Length > 0 && def_ref == "/AUTOSAR/Com/ComConfig/ComSignal")
            {
                List<XElement> def_ref1 = container.Descendants(ns + "FUNCTION-NAME-VALUE").Descendants(ns + "DEFINITION-REF").ToList();

                List<XElement> values = container.Descendants(ns + "FUNCTION-NAME-VALUE").Descendants(ns + "VALUE").ToList();

                foreach (XElement def in def_ref1)
                {
                    if ((string)def.Value == "/AUTOSAR/Com/ComConfig/ComSignal/ComNotification")
                    {
                        foreach (XElement value in values)
                        {
                                value.Value = "RTE_cbkTOut" + shortName;
                                listBox1.Items.Add(value.Value);
                        }
                    }
                }
            }
        }
        doc.Save(OpenFileDialog.FileName);
    }

This is one part of the XML file, there are too many such < containers> in my XML file. Here the name of the signal is defined in the tag < SHORT-NAME> , i want to change the innertext of the tag < VALUE> existing in the tag < FUNCTION-NAME-VALUE> with the signal name with some prefix. For Example: RTE_ComCbk_SignalName.

This has to be done in all the different containers existing in the XML file.

Please note: the structure remains the same for all the containers, only the inner text in the tags vary for the containers. I am able to write the prefix of the above said < Value> tag, How should I assign the Signal name for the tag < Value> ??

How should I proceed further?

 private void button11_Click(object sender, EventArgs e)
    {
    int count_ComTimeoutNotification = 0;
    XmlNodeList comTimeoutNotificationList = doc.GetElementsByTagName("DEFINITION-REF");
    int NodeListCount = comTimeoutNotificationList.Count;
    for (int i = 0; i < NodeListCount; i++)
        {


            if ((string)comTimeoutNotificationList[i].InnerText == "/AUTOSAR/Com/ComConfig/ComSignal/ComTimeoutNotification")
            {

                if ((string)comTimeoutNotificationList[i].NextSibling.Name == "VALUE")
                {
                    comTimeoutNotificationList[i].NextSibling.InnerText = "_Shree";
                    count_ComTimeoutNotification++; //this line is for reference if its changing the exact no.of time that is reqd.
                }
            }
        }

doc.Save(OpenFileDialog1.FileName); }

sre
  • 67
  • 9
  • I have added the part of the code for the above said operation. I dont know how to fetch the signal name and add it to the innertext of the tag – sre Apr 15 '16 at 09:35

3 Answers3

1

Try something like this using XML Linq

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


namespace ConsoleApplication85
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            XNamespace ns = ((XElement)doc.FirstNode).Name.Namespace;

            List<XElement> containers = doc.Descendants(ns + "CONTAINER").ToList();
            foreach (XElement container in containers)
            {
                var definition_Ref = container.Descendants(ns + "FUNCTION-NAME-VALUE")
                    .Where(x => x.Descendants(ns + "DEFINITION-REF").Count() > 0).ToList();
                if (definition_Ref.Count > 0)
                {
                    string shortName = (string)container.Element(ns + "SHORT-NAME");
                    if (shortName.Length > 0)
                    {
                        List<XElement> functionName = definition_Ref
                            .Where(x => x.Value.Contains("/AUTOSAR/Com/ComConfig/ComSignal/ComTimeoutNotification"))
                            .ToList();
                        XElement value = functionName.Elements("VALUE").FirstOrDefault();
                        if (value != null)
                        {
                            value.Value = shortName + "_" + value.Value;
                        }
                    }
                }
            }
        }
    }
}
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • i think this will change for all the tags in the xml file, i only want to do it specifically for only those tags that come under the tag : , under the tag: /AUTOSAR/Com/ComConfig/ComSignal/ComTimeoutNotification – sre Apr 15 '16 at 09:53
  • Change line to this : List values = container.Descendants("FUNCTION-NAME-VALUE").Descendants("VALUE").ToList(); – jdweng Apr 15 '16 at 10:03
  • I'm getting error at this line : string shortName = container.Element("SHORT-NAME").Value; Error: Object reference not set to an instance of an object – sre Apr 15 '16 at 10:21
  • It indicates that you have a container (not the one posted) that doesn't have a shortname. So I modified the code to skip any container that doesn't have a shortname. Also modified code to work with more than one container. – jdweng Apr 15 '16 at 10:28
  • I'm getting an error at this line: List containers = doc1.Elements("CONTAINER"); Cannot implicitly convert type 'System.Collections.Generic.IEnumerable' to 'System.Collections.Generic.List'. An explicit conversion exists (are you missing a cast?) – sre Apr 16 '16 at 05:12
  • Fixed. Added ToList(). – jdweng Apr 16 '16 at 09:36
  • The errors were cleared, when I run the program, how to check if the value is changed? How to write back to the xml file and save it? – sre Apr 16 '16 at 12:18
  • I tried adding a bool value and check if its entering the loop as follows: foreach (XElement value in values) { value.Value = shortName + "_" + value.Value; abc = true; } if (abc == true) { MessageBox.Show("Success"); } else { MessageBox.Show("Fail"); } The value obtained is always False! – sre Apr 16 '16 at 12:27
  • You can use the doc.Save(Filename) to write updated xml. The code works with posted xml. XML tag names are case sensity so the tag names must match exactly. My best guess right now is 'container' property is empty. Is 'CONTAINER' the root tag in the xml? – jdweng Apr 16 '16 at 15:22
  • AUTOSAR is the root element of the xml – sre Apr 17 '16 at 04:03
  • I had to change Elements to Descendents in following since CONTAINER wasn't the root tag : List containers = doc.Descendants("CONTAINER").ToList(); – jdweng Apr 17 '16 at 06:35
  • It seems that the 1st foreach loop is not being entered, the code is skipping the foreach loop, I can share the xml file with you for a clear reference. (Since my task is to deal with the XML's with the same structure through this application) – sre Apr 17 '16 at 07:43
  • the link for the XML: https://drive.google.com/open?id=0By5BxgNi9eGcRldxcEZNU0FDTzQ – sre Apr 17 '16 at 07:50
  • The xml you posted has a namespace so I had to modify code to work with the namespace. The XML you posted had lots of error to due extra carriage returns and ther xml file wasn't complete (missing end tags at the end of the xml). Sinced you aren't getting any error I assume the xml error occurred due to the way you posted the xml on the webpage. – jdweng Apr 17 '16 at 11:39
  • This is working pretty fine for me now! I made some edits as follows: string def_ref = (string)container.Element(ns + "DEFINITION-REF").Value.ToString(); //I added this line below the other string if (shortName.Length > 0 && def_ref == "/AUTOSAR/Com/ComConfig/ComSignal") { //The same procedure with a view into the listbox! } I want to append TEXT_shortName to /AUTOSAR/Com/ComConfig/ComSignal/ComTimeoutNotification (this is the DEFINITION-REF innertext) AND TEXT_1_shortName to /AUTOSAR/Com/ComConfig/ComSignal/ComNotification – sre Apr 18 '16 at 04:40
  • if i give the string compare with "/AUTOSAR/Com/ComConfig/ComSignal/ComTimeoutNotification" , the loop does not function and if I give the string compare as "/AUTOSAR/Com/ComConfig/ComSignal", the edit is made for both "/AUTOSAR/../../ComSignal/ComTimeOutNotification" and "/AUTOSAR/../../ComSignal/ComNotification" What should be the changes made to my function ? – sre Apr 18 '16 at 04:46
  • You can either use the index (either zero or one) or use string contains ComTimeoutNotification in the for loop : if(value.Value.Contains("ComTimeoutNotification")) – jdweng Apr 18 '16 at 09:21
  • i want to change values to the tag in the following manner: /AUTOSAR/Com/ComConfig/ComSignal/ComTimeoutNotification Text_shortName I want to change the innertext of the tag with the above said which is inside How can i do this?? – sre Apr 18 '16 at 09:35
  • i want to check with the tag if it contains "/AUTOSAR/Com/ComConfig/ComSignal/ComTimeoutNotification" , only then, i have to update the text in the tag – sre Apr 18 '16 at 09:56
  • I have tried this so far(refer to the code edit), but its updating to both "/AUTOSAR/Com/ComConfig/ComSignal/ComTimeoutNotification" & "/../../../../ComNotification" – sre Apr 18 '16 at 12:34
  • The xml post on the website and the one you have in this posting aren't the same. The website doesn't have ComSignal/ComTimeoutNotification – jdweng Apr 18 '16 at 13:10
  • I tried opening in Notepad++, it says 57 matches found for ComSignal/ComTimeoutNotification Anyway, I will update the file and share the link here – sre Apr 18 '16 at 13:18
  • It's now making changing in all the places where tag is available in the XML. (please see: my code edit is limiting the changes only to available with /AUTOSAR/Com/ComConfig/ComSignal/ComTimeoutNotification and /../../../../ComNotification I know there is some wrong logic used by me in the "foreach(XElement def in def_ref1)" loop but somehow i was able to limit the editing function to the above said tags! ) – sre Apr 18 '16 at 13:30
  • Still the edit is being done for both tag of both, "/../../../../ComNotification" and "/../../../../ComTimeoutNotification" – sre Apr 18 '16 at 14:39
  • please note: if the definition ref is /../../../../ComNotification", I want to edit it as "Text_SignalName" and if its "/../../../../ComTimeoutNotification", i would like to edit it as "Different_Text_SignalName" – sre Apr 18 '16 at 14:50
  • I think this line: List values = container.Descendants(ns + "FUNCTION-NAME-VALUE").Descendants(ns + "VALUE").ToList(); is fetching both "/../../../../ComNotification" and "/../../../../ComTimeoutNotification" due to which the value is updated for both the tags – sre Apr 18 '16 at 15:00
  • Are you using the latest code? It is impossible to be matching both ComNotification and ComTimeoutNotification. You should be able to modify the existing code and get it working. – jdweng Apr 18 '16 at 16:10
  • I did use the new code, i dont know why but its changing both the tags – sre Apr 18 '16 at 16:13
  • The code is making two changes both are ComTimeoutNoticiation. The xml has ... Note: Container is a child of Container. – jdweng Apr 18 '16 at 16:30
  • i think its something to do with the foreach(XElement value in values) its fetching all tags in the tag – sre Apr 18 '16 at 16:32
  • I am saving the file to a new location and on a check, i can see that both the values i.e for "/../../../../ComNotification" and "/../../../../ComTimeoutNotification" are getting edited! – sre Apr 18 '16 at 16:36
  • Found the problem and fixed it. – jdweng Apr 18 '16 at 20:14
  • The code is now changing the tag as follows : shortName_value.Value/AUTOSAR/Com/ComConfig/ComSignal/ComTimeoutNotification – sre Apr 19 '16 at 02:41
  • The tag should not be altered but only the tag – sre Apr 19 '16 at 02:42
  • Can it be done something like, with reference to the containing /../../../../ComTimeoutNotification and then selecting the node next to the above mentioned tag?? – sre Apr 19 '16 at 08:30
  • Nothing is being changed now, the values are nowhere updated in the whole of XML, it seems that the "if" condition is throwing a false value – sre Apr 19 '16 at 09:31
  • I just check the code using BeyondCompare to compare original xml against changed code and it seem to be working fine. I also added a break point inside the 'if' and it is reaching the break point. – jdweng Apr 19 '16 at 10:58
  • I have added the code written by me in the question, the edit is working pretty fine for me, but i don't know how to fetch the tag. it want that to be: comTimeoutNotificationList[i].NextSibling.InnerText = **.InnerText** + "_TEXT"; Can you help me out on this? I have not added the namespace either (would be helpful if u can help me adding namespace without using LINQ with XML) – sre Apr 19 '16 at 11:08
  • You already have the shortname in your code as a string which is the innertext. Why are you trying to get it again? – jdweng Apr 19 '16 at 12:20
  • The text in bold case in the above comment is for your reference ( i mean to say the value of the bold text has to be placed there) for example: **ABC** , the value of the tag **** should be replaced as **ABC** _TEXT – sre Apr 19 '16 at 13:06
  • The code should look similar to what I posted which is working. You don't need the foreach loop. Just follow what I did. – jdweng Apr 19 '16 at 14:28
  • For the time being, i will try without using LINQ, if it doesn't work I'll take this as an alternate way of changing the innertext value This has helped me a lot so far Thanks for the support :) – sre Apr 19 '16 at 14:57
  • I have a new issue similar to this post, i guess you can surely help me out on this The link is here: http://stackoverflow.com/questions/36740480/adding-a-new-node-to-a-nodelist-using-foreach-loop-and-xmlnodelist-c-sharp – sre Apr 20 '16 at 10:35
0

There is no need to use XML Linq the XmlDocument you already have should be capable of doing this using the SelectNodes and SelectSingleNodes methods and a little XPath like this:

        XmlNodeList list = doc.SelectNodes("//FUNCTION-NAME-VALUE/VALUE");
        foreach (XmlNode node in list)
        {
            XmlNode shortNameNode = node.SelectSingleNode("../../../SHORT-NAME");
            node.InnerText = "RTE_ComCbk_" + shortNameNode.InnerText;
        }
Martin Brown
  • 24,692
  • 14
  • 77
  • 122
  • I tried this out, and also tried to display the same in a listbox(just to check if it works the way I would like it to), i dont see any update in the listbox, For selecting a singlenode SHORT-NAME, I used the following path: "AUTOSAR/TOP-LEVEL-PACKAGES/AR-PACKAGE/ELEMENTS/MODULE-CONFIGURATION/CONTAINERS/CONTAINER/SUB-CONTAINERS/CONTAINER/SHORT-NAME" with AUTOSAR being the root element of the XML. Is the path described as above is correct? – sre Apr 15 '16 at 11:17
  • To get the full path, i have used treeView1.SelectedNode.FullPath command (i have a treeview window in my application) – sre Apr 15 '16 at 11:23
  • It is hard to know if the path is correct as I don't know what the schema of your XML file is above the CONTAINER element. However if you are not getting any results, it would suggest that it is probably wrong. – Martin Brown Apr 15 '16 at 13:38
  • Will the above code overwrite in the xml or do I have to save it back? – sre Apr 15 '16 at 14:09
  • I checked if the "foreach" loop is being entered on execution, but it turns out the program is unable to get into the loop. – sre Apr 16 '16 at 12:40
  • @jdweng I could figure out the way to get the values edited! Please find my answer and suggest me if I could optimize it anymore :) – sre Apr 19 '16 at 12:19
0
 private void button11_Click(object sender, EventArgs e)
    {
        XmlNodeList comTimeoutNotificationList = doc.GetElementsByTagName("DEFINITION-REF");
        int NodeListCount = comTimeoutNotificationList.Count;
        foreach (XmlNode node in comTimeoutNotificationList)
        {
            if (node.InnerText == "/AUTOSAR/Com/ComConfig/ComSignal")
            {
                if(node.PreviousSibling.Name == "SHORT-NAME")
                shortName = node.PreviousSibling.InnerText;
            }
            if (node.InnerText == "/AUTOSAR/Com/ComConfig/ComSignal/ComTimeoutNotification")
            {
                node.NextSibling.InnerText ="ComTout_" +  shortName;
                listBox1.Items.Add(node.NextSibling.InnerText);
            }
            else if(node.InnerText == "/AUTOSAR/Com/ComConfig/ComSignal/ComNotification")
            {
                node.NextSibling.InnerText = "ComNoti_" + shortName;
                listBox1.Items.Add(node.NextSibling.InnerText);
            }
            else if(node.InnerText == "/AUTOSAR/Com/ComConfig/ComSignal/ComInvalidNotification")
            {
                node.NextSibling.InnerText = "ComInval" + shortName;
                listBox1.Items.Add(node.NextSibling.InnerText);
            }
        }

    }
sre
  • 67
  • 9