XML parsing in Remote Provisioning ProvisioningTemplate.

%3CLINGO-SUB%20id%3D%22lingo-sub-47754%22%20slang%3D%22en-US%22%3EXML%20parsing%20in%20Remote%20Provisioning%20ProvisioningTemplate.%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-47754%22%20slang%3D%22en-US%22%3E%3CP%3EHi%20All%2C%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EI%20encountered%20an%20issue%20when%20trying%20to%20save%20off%20a%20template%20using%20ProvisioningTemplate.%26nbsp%3B%20Whenever%20I%20have%20a%20custom%20column%20or%20list%20name%20with%20non-xmlable%20characters%20in%20them%20I%20get%20an%20exception%20XmlException%20was%20unhandled.%26nbsp%3B%20The%20expected%20token%20is%20%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EThis%20happens%20when%20a%20List%20name%20for%20export%20to%20xml%20is%20something%20like%20%22R%26amp%3BD%202016%22%20to%20me%20a%20perfectly%20valid%20name%20and%20one%20our%20customers%20use%20often.%26nbsp%3B%20This%20occurs%20when%20I%20try%20to%20do%20GetProvisioningTemplate%20to%20the%20site%20containing%20the%20list.%26nbsp%3B%20I%20was%20surprised%20to%20see%20in%20the%20feb%2010%20release%20of%20the%20PNP%20library%20that%20there%20isn't%20a%20SecurityElement.Escape%20(string)%20call%20in%20XExtensions.cs%20(%3C%2FP%3E%3CP%3E%3CFONT%20color%3D%22%230000ff%22%20face%3D%22Consolas%22%20size%3D%222%22%3Enamespace%3C%2FFONT%3E%3CFONT%20face%3D%22Consolas%22%20size%3D%222%22%3E%20OfficeDevPnP.Core.Framework.Provisioning.Providers.Xml%3C%2FFONT%3E)%26nbsp%3B%20when%20making%20calls%20to%20things%20like%20ToXElement(String%20xml)%3B%26nbsp%3B%20WHen%20I%20replace%20with%20'%26amp%3B'%20with%20'%26amp%3Bamp%3B'%20the%20string%20parses%20just%20fine.%26nbsp%3B%20I'm%20not%20sure%20where%20to%20fix%20on%20the%20return%20trip%20for%20writing%20back%20to%20sharepoint%20yet.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EI'm%20new%20to%20Sharepoint%2C%20is%20there%20a%20best%20practice%20not%20to%20use%20un-escaped%20characters%20in%20lists%20and%20fields%20and%20that's%20why%20escaping%20isn't%20done%3F%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EThank%20you.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-47906%22%20slang%3D%22en-US%22%3ERe%3A%20XML%20parsing%20in%20Remote%20Provisioning%20ProvisioningTemplate.%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-47906%22%20slang%3D%22en-US%22%3E%3CP%3EI%20did%20more%20digging%20and%20have%20a%20better%20understanding%20of%20the%20issue.%26nbsp%3B%20In%20cases%20where%20we%20have%20a%20custom%20column%26nbsp%3Bassocaited%20with%20a%20list%20that%20has%20a%20non%20xmlable%20character%20in%20it%20E.g.%20List%20title%20%3D%20%222016%20R%26amp%3BD%22%2C%20the%20PNP%20code%20will%20try%20to%20put%20a%20token%20into%20the%26nbsp%3BSourceID%20to%20replace%20the%20Guid%20that%20associates%20the%20column%20with%20the%20list.%26nbsp%3B%20So%20in%20this%20case%20SourceID%20was%20a%20GUID%20it%20becomes%26nbsp%3B%22%7B%7Blistid%3A%7Blist.Title%7D%7D%7D%22%26nbsp%3B%20which%20is%20%22listid%3A%202016%20R%26amp%3BD%22.%26nbsp%3B%20This%26nbsp%3Bcan't%20be%20handled%20by%20xml%20parser%20later%20on%20when%20writing%20it%20to%20disk.%26nbsp%3B%20I%20am%20testing%20a%20fix%20that%20when%20the%20PNP%20code%20reads%20the%20lists%20from%20CSOM%20for%20the%20site%20it%26nbsp%3Bfixes%20up%20the%20Title%20to%20be%20xmlable%20so%20%26amp%3B%20becomes%26nbsp%3B%26amp%3Bamp%3B%26nbsp%3Betc...%26nbsp%3B%20Worked%20to%20serialize%20to%20disk%2C%20am%20working%26nbsp%3Bon%20the%20round%20trip.%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%3Eprivate%20string%20ParseFieldSchema(string%20schemaXml%2C%20Web%20web%2C%20List%26lt%3BList%26gt%3B%20lists)%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20foreach%20(var%20list%20in%20lists)%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20schemaXml%20%3D%20Regex.Replace(schemaXml%2C%20list.Id.ToString()%2C%20%24%22%7B%7Blistid%3A%7Blist.Title%7D%7D%7D%22%2C%20RegexOptions.IgnoreCase)%3B%0A.%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-47782%22%20slang%3D%22en-US%22%3ERe%3A%20XML%20parsing%20in%20Remote%20Provisioning%20ProvisioningTemplate.%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-47782%22%20slang%3D%22en-US%22%3E%3CP%3EThere's%20no%20best%20practice%20describing%20you%20should%20not%20use%20un-escaped%20characters.%20There%20are%20some%20character%20limitations%20in%20naming%20SharePoint%20elements%20but%20the%20GetProvisioningTemplate%20method%20should%20just%20work%20with%20any%20allowed%20character.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EI'd%20suggest%20you%20to%20submit%20an%20issue%20in%20the%20OfficeDevPnP.Core%20repository%20on%20GitHub%20so%20you%2C%20me%20or%20someone%20else%20can%20take%20a%20look%20at%20it%20and%20fix%20it%20%3A)%3C%2Fimg%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2FSharePoint%2FPnP-Sites-Core%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3Ehttps%3A%2F%2Fgithub.com%2FSharePoint%2FPnP-Sites-Core%3C%2FA%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-47766%22%20slang%3D%22en-US%22%3ERe%3A%20XML%20parsing%20in%20Remote%20Provisioning%20ProvisioningTemplate.%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-47766%22%20slang%3D%22en-US%22%3E%3CP%3ESeems%20SecurityElement.Escape%26nbsp%3B%20isn't%20the%20solution%20it%20also%20replaces%20%26lt%3B%26gt%3B%26nbsp%3B%26nbsp%3B%20%3A(%3C%2Fimg%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E
Occasional Contributor

Hi All,

 

I encountered an issue when trying to save off a template using ProvisioningTemplate.  Whenever I have a custom column or list name with non-xmlable characters in them I get an exception XmlException was unhandled.  The expected token is ;

 

This happens when a List name for export to xml is something like "R&D 2016" to me a perfectly valid name and one our customers use often.  This occurs when I try to do GetProvisioningTemplate to the site containing the list.  I was surprised to see in the feb 10 release of the PNP library that there isn't a SecurityElement.Escape (string) call in XExtensions.cs (

namespace OfficeDevPnP.Core.Framework.Provisioning.Providers.Xml)  when making calls to things like ToXElement(String xml);  WHen I replace with '&' with '&' the string parses just fine.  I'm not sure where to fix on the return trip for writing back to sharepoint yet.

 

I'm new to Sharepoint, is there a best practice not to use un-escaped characters in lists and fields and that's why escaping isn't done?

 

Thank you.

 

 

 

3 Replies

Seems SecurityElement.Escape  isn't the solution it also replaces <>   :(   

There's no best practice describing you should not use un-escaped characters. There are some character limitations in naming SharePoint elements but the GetProvisioningTemplate method should just work with any allowed character.

 

I'd suggest you to submit an issue in the OfficeDevPnP.Core repository on GitHub so you, me or someone else can take a look at it and fix it :)

 

https://github.com/SharePoint/PnP-Sites-Core

 

 

I did more digging and have a better understanding of the issue.  In cases where we have a custom column assocaited with a list that has a non xmlable character in it E.g. List title = "2016 R&D", the PNP code will try to put a token into the SourceID to replace the Guid that associates the column with the list.  So in this case SourceID was a GUID it becomes "{{listid:{list.Title}}}"  which is "listid: 2016 R&D".  This can't be handled by xml parser later on when writing it to disk.  I am testing a fix that when the PNP code reads the lists from CSOM for the site it fixes up the Title to be xmlable so & becomes &amp; etc...  Worked to serialize to disk, am working on the round trip. 

 

private string ParseFieldSchema(string schemaXml, Web web, List<List> lists)
        {
            foreach (var list in lists)
            {
                schemaXml = Regex.Replace(schemaXml, list.Id.ToString(), $"{{listid:{list.Title}}}", RegexOptions.IgnoreCase);
.