public string CreateUniqueParagraphId() { // Lazily retrieve it as the collection may be updated in the feature collection and we want to react to that change. var collection = _features.GetRequired <IParagraphIdCollectionFeature>(); var bytes = new byte[] { 0x00, 0x00, 0x00, 0x00 }; string?str; do { do { _randomNumber.GetBytes(bytes); }while (bytes[0] >= 0x80 || (bytes[0] == 0 && bytes[1] == 0 && bytes[2] == 0 && bytes[3] == 0)); str = HexStringFactory.Create(bytes); }while (collection.Contains(str)); return(str); }
public void AssignUniqueParagraphIds_WordDocumentWithNonUniqueIds_AllParaIdsUnique() { // Arrange. // Construct a document with 100 different w14:paraId values and many duplicates. const int count = 1000; const int divisor = 100; var body = new Body(); for (var i = 0; i < count; i++) { string paragraphId = HexStringFactory.Create(0x00, 0x00, 0x00, (byte)(i % divisor)) !; body.AppendChild(new Paragraph(new Run(new Text(paragraphId))) { ParagraphId = paragraphId }); } using var stream = new MemoryStream(); using var wordDocument = WordprocessingDocument.Create(stream, WordprocessingDocumentType.Document); wordDocument.AddParagraphIdFeature(); var paraIdCollection = wordDocument.Features.GetRequired <IParagraphIdCollectionFeature>(); var part = wordDocument.AddMainDocumentPart(); part.Document = new Document(body); // Assert. // We have as many registered w14:paraId values as we have w:p elements. Assert.Equal(count, paraIdCollection.Count); // When checked independently, the number of w14:paraId values matches. var newParaIds = new HashSet <string>(body.Elements <Paragraph>().Select(p => p.ParagraphId !.Value !)); Assert.Equal(count, newParaIds.Count); // The first 100 w:p elements did not have their w14:paraId value changed. Assert.All(body.Elements <Paragraph>().Take(divisor), p => Assert.Equal(p.InnerText, p.ParagraphId !.InnerText)); // The following 900 w:p elements did have their w14:paraId values changed. Assert.All(body.Elements <Paragraph>().Skip(divisor), p => Assert.NotEqual(p.InnerText, p.ParagraphId !.InnerText)); }