How to merge XDocument Files

Niladri.Biswas
Posted by in C# category on for Beginner level | Points: 250 | Views : 9955 red flag

This article will show us how to merge XDocument Files


 Download source code for How to merge XDocument Files

Introduction

Let us say that we have two XML structures as under

XML Structure1

<scriptfilenames>
  <SqlEye>
    <scriptfilename Name="ws_CallLogs_GetByCallId.sql" Type="SP">
      <SqlEyeWarnings>
        <SqlEyeWarning value="SD030:  object does not exist in database or is invalid for this operation in Database   : ws_CallLogs  @ line number : 63" />        
      </SqlEyeWarnings>
      <FxCopsWarnings>
        <FxCopsWarning value="Avoid using sp_ as a prefix for stored procedure " />        
      </FxCopsWarnings>
      <SqlEyeRemarks>
        <SqlEyeRemark value="SP017: Consider using EXISTS predicate instead of IN predicate  @ line number : 1" />
      </SqlEyeRemarks>
      <FxCopsRemarks>
        <FxCopsRemark value="Missing or order mismatch of Grant statement." />
      </FxCopsRemarks>
    </scriptfilename>
  </SqlEye>
</scriptfilenames>

XML Structure2

<scriptfilenames>
  <SqlEye>
    <scriptfilename Name="dbo.StopAutoRenewalEx.StoredProcedure.sql" Type="SP">
      <SqlEyeWarnings />
      <FxCopsWarnings>       
        <FxCopsWarning value="Missing schema while addressing object name" />
      </FxCopsWarnings>
      <SqlEyeRemarks>
        <SqlEyeRemark value="SP016: Update statements should not update primary key  @ line number : 70" />        
      </SqlEyeRemarks>
      <FxCopsRemarks>
        <FxCopsRemark value="Values hardcoded in where-clause condition " />        
      </FxCopsRemarks>
    </scriptfilename>
  </SqlEye>
</scriptfilenames>

Now after merge, the result should be

<scriptfilenames>
  <SqlEye>
    <scriptfilename Name="ws_CallLogs_GetByCallId.sql" Type="SP">
      <SqlEyeWarnings>
        <SqlEyeWarning value="SD030:  object does not exist in database or is invalid for this operation in Database   : ws_CallLogs  @ line number : 63" />        
      </SqlEyeWarnings>
      <FxCopsWarnings>
        <FxCopsWarning value="Avoid using sp_ as a prefix for stored procedure " />        
      </FxCopsWarnings>
      <SqlEyeRemarks>
        <SqlEyeRemark value="SP017: Consider using EXISTS predicate instead of IN predicate  @ line number : 1" />
      </SqlEyeRemarks>
      <FxCopsRemarks>
        <FxCopsRemark value="Missing or order mismatch of Grant statement." />
      </FxCopsRemarks>
    </scriptfilename>
    <scriptfilename Name="dbo.StopAutoRenewalEx.StoredProcedure.sql" Type="SP">
      <SqlEyeWarnings />
      <FxCopsWarnings>       
        <FxCopsWarning value="Missing schema while addressing object name" />
      </FxCopsWarnings>
      <SqlEyeRemarks>
        <SqlEyeRemark value="SP016: Update statements should not update primary key  @ line number : 70" />        
      </SqlEyeRemarks>
      <FxCopsRemarks>
        <FxCopsRemark value="Values hardcoded in where-clause condition " />        
      </FxCopsRemarks>
    </scriptfilename>
  </SqlEye>
</scriptfilenames>

This article will show two solutions to do the same.

Environment Setup

Let us first write the below code snippet for making the XML documents

private static XDocument FirstXMLStructure()
{
	var xmlContent = @"<scriptfilenames>
			  <SqlEye>
				<scriptfilename Name='ws_CallLogs_GetByCallId.sql' Type='SP'>
				  <SqlEyeWarnings>
					<SqlEyeWarning value='SD030:  object does not exist in database or is invalid for this operation in Database   : ws_CallLogs  @ line number : 63' />        
				  </SqlEyeWarnings>
				  <FxCopsWarnings>
					<FxCopsWarning value='Avoid using sp_ as a prefix for stored procedure ' />        
				  </FxCopsWarnings>
				  <SqlEyeRemarks>
					<SqlEyeRemark value='SP017: Consider using EXISTS predicate instead of IN predicate  @ line number : 1' />
				  </SqlEyeRemarks>
				  <FxCopsRemarks>
					<FxCopsRemark value='Missing or order mismatch of Grant statement.' />
				  </FxCopsRemarks>
				</scriptfilename>
			  </SqlEye>
			</scriptfilenames>";           
	return XDocument.Parse(xmlContent);
}

private static XDocument SecondXMLStructure()
{
	var xmlContent =@"<scriptfilenames>
			  <SqlEye>
				<scriptfilename Name='dbo.StopAutoRenewalEx.StoredProcedure.sql' Type='SP'>
				  <SqlEyeWarnings />
				  <FxCopsWarnings>       
					<FxCopsWarning value='Missing schema while addressing object name' />
				  </FxCopsWarnings>
				  <SqlEyeRemarks>
					<SqlEyeRemark value='SP016: Update statements should not update primary key  @ line number : 70' />        
				  </SqlEyeRemarks>
				  <FxCopsRemarks>
					<FxCopsRemark value='Values hardcoded in where-clause condition ' />        
				  </FxCopsRemarks>
				</scriptfilename>
			  </SqlEye>
			</scriptfilenames>";
	return XDocument.Parse(xmlContent);
}

Now use the below program to load the documents

static void Main(string[] args)
{
   var xmls = new List<XDocument>
   {      FirstXMLStructure(),
          SecondXMLStructure()
    };
}

Solution1

Use LINQ to XML to select the list of <scriptfilename>" elements and add them to a new XDocument

var resultXml1 = new XDocument
                (
                    new XElement("scriptfilenames",
                    new XElement("SqlEye",xmls.Descendants("scriptfilename")))
                );

Solution2

Extract the portion <scriptfilename>" and wrap it up using Stringbuilder for the Root Nodes.

StringBuilder sb = new StringBuilder();
sb.AppendLine("<scriptfilenames><SqlEye>");
int cnt = xmls.Count;

for (int i = 0; i < cnt; i++)
{
	var value = xmls[i];
	var findContent = value.Descendants("scriptfilename");
	sb.AppendLine(value.Descendants("scriptfilename").ToList()[0].ToString());
}

sb.AppendLine("</SqlEye></scriptfilenames>");
var resultXml2 = sb.ToString();

Among these two, I would prefer the first one as it is much more neat and clean and no extra string operation is needed.

Conclusion

So in this article we have learnt as how to join / merge two or more XDocument structures / files.Thanks for reading.Zipped file is attached.

Page copy protected against web site content infringement by Copyscape

About the Author

Niladri.Biswas
Full Name: Niladri Biswas
Member Level: Platinum
Member Status: Member
Member Since: 10/25/2010 11:04:24 AM
Country: India
Best Regards, Niladri Biswas
http://www.dotnetfunda.com
Technical Lead at HCL Technologies

Login to vote for this post.

Comments or Responses

Login to post response

Comment using Facebook(Author doesn't get notification)