0

I have 4 similar nodes with 4 different values. For example, I have the below values.

<sample>
        <a>123</a>
        <a>45</a>
        <a>67</a>
        <a>890</a>
</sample>

I need to check the length of each node and if its less than 3, then leading zeroes should be appended like below.

<sample>
        <a>123</a>
        <a>045</a>
        <a>067</a>
        <a>890</a>
</sample>

After appending leading zeroes, I need to concatenate all the values together and pass it as a single string.

<a>123045067890</a>

Please provide an optimum solution.

5
  • So a good solution wouldn't suffice, it must be optimum? Commented Apr 24, 2017 at 7:44
  • This is trivial to do in XSLT: just use the format-number() function in a xsl:for-each instruction. Commented Apr 24, 2017 at 8:12
  • @DanielShillcock Yes I have tried a piece of code. Commented Apr 24, 2017 at 9:10
  • @michael.hor257k I have used xsl:for-each command. But when I use that, only the first tag gets taken into account and not the second and other. Commented Apr 24, 2017 at 9:11
  • This is the code I have tried. Please put your thoughts. <xsl:for-each select="//a"> <ab> <xsl:choose> <xsl:when test="string-length(//a) &lt; 3"> <xsl:copy-of select="." /> </xsl:when> <xsl:otherwise>ERROR</xsl:otherwise> </xsl:choose> </ab> </xsl:for-each> Commented Apr 24, 2017 at 9:13

3 Answers 3

1

The following stylesheet:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="sample">
    <a>
        <xsl:for-each select="a">
            <xsl:value-of select="format-number(., '000')" />
        </xsl:for-each>
    </a>
</xsl:template>

</xsl:stylesheet>

applied to your example input, returns:

<?xml version="1.0" encoding="UTF-8"?>
<a>123045067890</a>
Sign up to request clarification or add additional context in comments.

Comments

1

here's one approach using XPath:

string xml = @"
    <sample>
        <a>123</a>
        <a>45</a>
        <a>67</a>
        <a>890</a>
    </sample>
";

//load xml
XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(xml);

//get all <a> nodes and cast them to List<XmlNode>
var nodes = xdoc.SelectNodes("sample/a")
    .Cast<XmlNode>().ToList();

//iterate through each node and append leading zeroes until length is 3 chars
nodes.ForEach(n => n.InnerText = n.InnerText.PadLeft(3, '0'));
//join all values and add tags to beginning and the end
string concatenatedValues = "<a>" + string.Join("", nodes.Select(x => x.InnerText).ToArray()) + "</a>";

Comments

0

You can try this:

string xml = @"<sample>
                        <a>123</a>
                        <a>45</a>
                        <a>67</a>
                        <a>890</a>
                    </sample>";

XDocument xmlDoc = XDocument.Parse(xml);
int value = 0;
StringBuilder errorsSb = new StringBuilder();
List<string> a_Nodes = new List<string>();

xmlDoc.Descendants("a").Select(x => x.Value).ToList().ForEach(x =>
{
     if (int.TryParse(x, out value))
          a_Nodes.Add(value.ToString("D3"));
     else
          errorsSb.AppendLine($"Value {value} is not a number");
     });

     string res = String.Join(string.Empty, a_Nodes);
     if (!string.IsNullOrWhiteSpace(errorsSb.ToString()))
     {
          // handle errors
     }
}

7 Comments

Your code would cause exceptions if non-numeric values are inside the <a> tags due to the int.Parse(x.Value)
@bradbury9, so you think it is not good behawior? Better will be just add zeros to any text? Or just skip invalid entry...? I disagree with you. Exception will inform that something is wrong with xml. And catching exception is not a part of the question.
Exceptions is a so heavy method to control input. Unhandled exceptions? IMHO should not happen. In this case you could use schemas (heavier), a foreach with int32.TryParse (lighter)
A foreach should perform the same as the Select and a TryParse would perform better than a try-catch + Parse stackoverflow.com/questions/150114/…
@bradbury9 daniell's answer isn't necessarily bad; OP did't specify which kind of data is expected in those <a> nodes and daniell assumed it's int, without exceptions. To get better answer, OP should define his/hers question with a bit more details. Anyhow, TryParse is better approach.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.