locked
How to update xml file node value using XmlDocument RRS feed

  • Question

  • This is my xml

    <?xml version="1.0" encoding="utf-8"?>
    <TickerBrokerStandardDateLineitem>
      <Ticker />
      <TickerID />
      <TickerBrokerStandardDateLineitemValues>
        <TickerBrokerStandardDateLineitemValue>
          <TabName>Consensus Model</TabName>
          <StandardDate>1Q 2010</StandardDate>
          <BRTab>IS</BRTab>
          <BRLineItem>Revenues</BRLineItem>
          <Action>Extracted</Action>
          <StandardLineItem>Net Revenue</StandardLineItem>
          <StandardValue>329.623</StandardValue>
        </TickerBrokerStandardDateLineitemValue>
        <TickerBrokerStandardDateLineitemValue>
          <TabName>Consensus Model</TabName>
          <StandardDate>2Q 2010</StandardDate>
          <BRTab>IS</BRTab>
          <BRLineItem>Revenues</BRLineItem>
          <Action>Extracted</Action>
          <StandardLineItem>Net Revenue</StandardLineItem>
          <StandardValue>454.776</StandardValue>
        </TickerBrokerStandardDateLineitemValue>
      </TickerBrokerStandardDateLineitemValues>
    </TickerBrokerStandardDateLineitem>	

    I tried to update node value this way. just compare and if value same then replace with new value

    System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
    xmlDoc.Load(xmlFile);
    
    IEnumerator ie = xmlDoc.SelectNodes("TickerBrokerStandardDateLineitem/TickerBrokerStandardDateLineitemValues/TickerBrokerStandardDateLineitemValue/StandardLineItem").GetEnumerator();
    
    while (ie.MoveNext())
    {
    	if ((ie.Current as XmlNode).Value.Trim().ToUpper() == "Net Revenue".Trim().ToUpper())
    	{
    		(ie.Current as XmlNode).Value = "Net Revenue 11";
    	}
    }
    
    xmlDoc.Save(xmlFile);

    but (ie.Current as XmlNode).Value is getting NULL

    please tell me how to update StandardLineItem if value match?

    thanks


    • Edited by Sudip_inn Monday, September 7, 2020 12:19 PM
    Monday, September 7, 2020 11:26 AM

Answers

  • Check two solutions:

    xmlDoc.SelectNodes( "TickerBrokerStandardDateLineitem/TickerBrokerStandardDateLineitemValues/TickerBrokerStandardDateLineitemValue/StandardLineItem[translate(normalize-space(.), 'NET REVENUE', 'net revenue')='net revenue']/text()" )
    	.Cast<XmlText>( )
    	.All( t => { t.Value = "Net Revenue 11"; return true; } );

    and

    xmlDoc.SelectNodes( "TickerBrokerStandardDateLineitem/TickerBrokerStandardDateLineitemValues/TickerBrokerStandardDateLineitemValue/StandardLineItem/text()" )
    	.Cast<XmlText>( )
    	.Where( t => t.Value.Trim( ).Equals( "Net Revenue", StringComparison.InvariantCultureIgnoreCase ) )
    	.All( t => { t.Value = "Net Revenue 11"; return true; } );

    You can also use foreach.

    It is also possible to use XSLT.




    • Marked as answer by Sudip_inn Monday, September 7, 2020 5:09 PM
    • Edited by Viorel_MVP Monday, September 7, 2020 7:40 PM Fixing letter case
    Monday, September 7, 2020 2:31 PM
  • [...]

    what i can fix in my code as a result it should work too ?

    [...]

    Try this fix:

    if( ( (XmlNode)ie.Current ).InnerText.Trim( ).ToUpper( ) == "Net Revenue".Trim( ).ToUpper( ) )
    {
       ( (XmlNode)ie.Current ).InnerText = "Net Revenue 11";
    }
    


    • Marked as answer by Sudip_inn Tuesday, September 8, 2020 9:09 AM
    Monday, September 7, 2020 5:21 PM
  • I understand your second set of code but first one not clear.

    [translate(normalize-space(.), 'Net Revenue', 'net revenue')='net revenue']/text()

    what is the meaning of this above line. please discuss it in more details.

    1) what is translate ? is it any function ? what it does ?

    2) what the dot is for (.) ?

    3) why 3 times net revenue mention ?

     'Net Revenue', 'net revenue')='net revenue' ?

    please discuss point wise

    thanks


    Translate is a function that replaces characters [https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/ms256119(v=vs.100)]. It is used here to replace uppercase letters with lowercase. However, the usage was defective. The fix is: translate(normalize-space(.), 'NET REVENUE', 'net revenue'), or, optimised, without repetitions: translate(normalize-space(.), 'NETRVU', 'netrvu'). The code will be corrected.

    Then the result is compared with ‘net revenue’, which was already typed in lowercase.

    Although, there is a better function — lower-case(  ) —, which is not available in this version.

    “.” means the current node, in this case: <StandardLineItem>.



    • Edited by Viorel_MVP Monday, September 7, 2020 7:40 PM
    • Marked as answer by Sudip_inn Tuesday, September 8, 2020 9:12 AM
    Monday, September 7, 2020 5:42 PM
  • Thanks for explanation. some what clear but still this not clear

    1) StandardLineItem[translate(normalize-space(.), 'NET REVENUE', 'net revenue')='net revenue']/text()

    why there are two Net Revenue ? one in caps and one in small ?

    2) see this [translate(normalize-space(.), 'NET REVENUE', 'net revenue')='net revenue']

    why there is = sign ? and there is Net Revenue after = sign ? objective not clear.

    please explain

    The expression “....../StandardLineItem[translate(normalize-space(.), 'NET REVENUE', 'net revenue')='net revenue']” means:

    • Get <StandardLineItem> elements and filter them according to condition that is specified inside “[…]”
    • The condition is “=” (equals), used in this manner:
      • Remove spaces from the text of current <StandardLineItem> using normalize-space function, and pass the result to translate function
      • Translate function, according to Documentation, takes two more arguments; the second one — “NET REVENUE” — lists eleven characters that will be replaced with corresponding characters from the third argument. I.e. ‘N’ will be replaced with ‘n’, ‘E’ with ‘e’, ‘T’ with ‘t’, etc. (This was the simplified approach because it admits some repetitions; the reasonable approach is: translate(…, “NETRVU”, “netrvu”)).
      • Translate function was used here to convert the possible variants of “Net Revenue” to lower-case form. Then the result is compared using “=” with expected ‘net revenue’ text.
      • If the text was different, then the condition returns false and the node is skipped. Otherwise the node is returned.

    • Marked as answer by Sudip_inn Wednesday, September 9, 2020 6:53 AM
    Tuesday, September 8, 2020 10:04 AM

All replies

  • Check two solutions:

    xmlDoc.SelectNodes( "TickerBrokerStandardDateLineitem/TickerBrokerStandardDateLineitemValues/TickerBrokerStandardDateLineitemValue/StandardLineItem[translate(normalize-space(.), 'NET REVENUE', 'net revenue')='net revenue']/text()" )
    	.Cast<XmlText>( )
    	.All( t => { t.Value = "Net Revenue 11"; return true; } );

    and

    xmlDoc.SelectNodes( "TickerBrokerStandardDateLineitem/TickerBrokerStandardDateLineitemValues/TickerBrokerStandardDateLineitemValue/StandardLineItem/text()" )
    	.Cast<XmlText>( )
    	.Where( t => t.Value.Trim( ).Equals( "Net Revenue", StringComparison.InvariantCultureIgnoreCase ) )
    	.All( t => { t.Value = "Net Revenue 11"; return true; } );

    You can also use foreach.

    It is also possible to use XSLT.




    • Marked as answer by Sudip_inn Monday, September 7, 2020 5:09 PM
    • Edited by Viorel_MVP Monday, September 7, 2020 7:40 PM Fixing letter case
    Monday, September 7, 2020 2:31 PM
  • I understand your second set of code but first one not clear.

    [translate(normalize-space(.), 'Net Revenue', 'net revenue')='net revenue']/text()

    what is the meaning of this above line. please discuss it in more details.

    1) what is translate ? is it any function ? what it does ?

    2) what the dot is for (.) ?

    3) why 3 times net revenue mention ?

     'Net Revenue', 'net revenue')='net revenue' ?

    please discuss point wise

    thanks

    Monday, September 7, 2020 5:12 PM
  • also tell me what was wrong in my code ?

    what i can fix in my code as a result it should work too ?

    System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
    xmlDoc.Load(xmlFile);
    
    IEnumerator ie = xmlDoc.SelectNodes("TickerBrokerStandardDateLineitem/TickerBrokerStandardDateLineitemValues/TickerBrokerStandardDateLineitemValue/StandardLineItem").GetEnumerator();
    
    while (ie.MoveNext())
    {
    	if ((ie.Current as XmlNode).Value.Trim().ToUpper() == "Net Revenue".Trim().ToUpper())
    	{
    		(ie.Current as XmlNode).Value = "Net Revenue 11";
    	}
    }
    
    xmlDoc.Save(xmlFile);

    Monday, September 7, 2020 5:13 PM
  • [...]

    what i can fix in my code as a result it should work too ?

    [...]

    Try this fix:

    if( ( (XmlNode)ie.Current ).InnerText.Trim( ).ToUpper( ) == "Net Revenue".Trim( ).ToUpper( ) )
    {
       ( (XmlNode)ie.Current ).InnerText = "Net Revenue 11";
    }
    


    • Marked as answer by Sudip_inn Tuesday, September 8, 2020 9:09 AM
    Monday, September 7, 2020 5:21 PM
  • I understand your second set of code but first one not clear.

    [translate(normalize-space(.), 'Net Revenue', 'net revenue')='net revenue']/text()

    what is the meaning of this above line. please discuss it in more details.

    1) what is translate ? is it any function ? what it does ?

    2) what the dot is for (.) ?

    3) why 3 times net revenue mention ?

     'Net Revenue', 'net revenue')='net revenue' ?

    please discuss point wise

    thanks


    Translate is a function that replaces characters [https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/ms256119(v=vs.100)]. It is used here to replace uppercase letters with lowercase. However, the usage was defective. The fix is: translate(normalize-space(.), 'NET REVENUE', 'net revenue'), or, optimised, without repetitions: translate(normalize-space(.), 'NETRVU', 'netrvu'). The code will be corrected.

    Then the result is compared with ‘net revenue’, which was already typed in lowercase.

    Although, there is a better function — lower-case(  ) —, which is not available in this version.

    “.” means the current node, in this case: <StandardLineItem>.



    • Edited by Viorel_MVP Monday, September 7, 2020 7:40 PM
    • Marked as answer by Sudip_inn Tuesday, September 8, 2020 9:12 AM
    Monday, September 7, 2020 5:42 PM
  • Thanks for explanation. some what clear but still this not clear

    1) StandardLineItem[translate(normalize-space(.), 'NET REVENUE', 'net revenue')='net revenue']/text()

    why there are two Net Revenue ? one in caps and one in small ?

    2) see this [translate(normalize-space(.), 'NET REVENUE', 'net revenue')='net revenue']

    why there is = sign ? and there is Net Revenue after = sign ? objective not clear.

    please explain

    Tuesday, September 8, 2020 9:14 AM
  • Thanks for explanation. some what clear but still this not clear

    1) StandardLineItem[translate(normalize-space(.), 'NET REVENUE', 'net revenue')='net revenue']/text()

    why there are two Net Revenue ? one in caps and one in small ?

    2) see this [translate(normalize-space(.), 'NET REVENUE', 'net revenue')='net revenue']

    why there is = sign ? and there is Net Revenue after = sign ? objective not clear.

    please explain

    The expression “....../StandardLineItem[translate(normalize-space(.), 'NET REVENUE', 'net revenue')='net revenue']” means:

    • Get <StandardLineItem> elements and filter them according to condition that is specified inside “[…]”
    • The condition is “=” (equals), used in this manner:
      • Remove spaces from the text of current <StandardLineItem> using normalize-space function, and pass the result to translate function
      • Translate function, according to Documentation, takes two more arguments; the second one — “NET REVENUE” — lists eleven characters that will be replaced with corresponding characters from the third argument. I.e. ‘N’ will be replaced with ‘n’, ‘E’ with ‘e’, ‘T’ with ‘t’, etc. (This was the simplified approach because it admits some repetitions; the reasonable approach is: translate(…, “NETRVU”, “netrvu”)).
      • Translate function was used here to convert the possible variants of “Net Revenue” to lower-case form. Then the result is compared using “=” with expected ‘net revenue’ text.
      • If the text was different, then the condition returns false and the node is skipped. Otherwise the node is returned.

    • Marked as answer by Sudip_inn Wednesday, September 9, 2020 6:53 AM
    Tuesday, September 8, 2020 10:04 AM