RSS feed- Using WriteTo to update an existing TextSyndicationContent - c#

I'm helping out with an open-source project. In it, we are getting a feed (open using Chrome) using var feed = new SyndicationFeed(...){...}; that contains different article titles along with their names.
After that I am able to iterate through the feed using foreach(var item in feed.Items){} and in there I can get the Title & Name string using item.Title.Text & item.Authors[0].Name.
The problem is that these properties are read-only, but I want to be able to add some text to the end of the Title property. So, the only way to update the Title (since it's of type TextSyndicationContent) seems to be by using item.Title.WriteTo()
How I can use the WriteTo to update the value of the existing Title without creating a new RSS Feed? Also, how can I get the outerElementName & outerElementNamespace?
I have added a screenshot of what the function requires me to put in.
Is the outerElementName "title" and outerElementNamespace "group? If so, what can I put in as XMLWriter to update the value of title?

The Title property can be set on the item.
Create a new instance of TextSyndicationContent and copy over the title with the additional text.
//...
string newTitleText = item.Title.Text + "Some extra text content";
if (!string.IsNullOrWhiteSpace(item.Title.Type)) {
string type = item.Title.Type == "text" ? "Plaintext" : item.Title.Type;
TextSyndicationContentKind textKind = (TextSyndicationContentKind)
Enum.Parse(typeof(TextSyndicationContentKind), type, ignoreCase: true);
item.Title = new TextSyndicationContent(newTitleText, textKind);
} else {
item.Title = new TextSyndicationContent(newTitleText);
}
//...

Related

52/5000 How to get a certain value in html code by c #

i want search spacial value in html code by webbrowser in c#. for example html code<span class="pulser " data-dollari="164.843956376000000" eq_toman="_XcUOV" pulser-change="_OiuVD" pre-dollari="164.964899983000000">$164.97</span>i need Getting the value "164.964899983000000" and another value html code.
If I understand you correctly, you want to get an element from a site and get its attribute values like 'pre-dollari'.
For c#, you can use ScrapySharp , it's a library where you can simulate a webbrowser and scrape its contents. You can use it alongside htmlAgilityPack
to effectively traverse the elements.
So for your case, it could look like this.
// get your Url
Uri url = new Uri("Yoursite.com");
// open up the browser
ScrapingBrowser browser = new ScrapingBrowser();
// navigate to your page
WebPage page = browser.NavigateToPage(url, HttpVerb.Post, "", null);
// find your element, convert to a list and take the first result [0]
HtmlNode node2 = page.Find("span", By.Class("pulser")).ToList()[0];
// and now you can get the attribute by name and put it in a variable
string attributeValue = node2.GetAttributeValue("pre-dollari", "not found");
// attributeValue = 164.964899983000000

OpenXML Remove text from template

I have a number of .docx templates that customers download, but certain words need to be changed or removed from the document for different customers. I can't find anything on how to remove text:-
using (WordprocessingDocument doc = WordprocessingDocument.Open(memoryStream, true))
{
foreach (Text element in doc.MainDocumentPart.Document.Body.Descendants<Text>())
{
//This is fine
element.Text = element.Text.Replace("DocumentDate", wordReferenceTemplatesMV.DocumentDate)
//Need help on how to remove text
element.Text = element.Text.Remove???("TextToRemove")
}
Why not just replace it with an empty string?
element.Text = element.Text.Replace("TextToRemove", string.Empty);
Most text values are in Run element. Basically you can run through all the Run elements and check its text. it should be something like:
Body body = wordprocessingDocument.MainDocumentPart.Document.Body;
foreach (Run r in body.Descendants<Run>())
{
string sText = r.InnerText ;
//...compare the text with the value
//note sometime, you could see the text be broken into two runs, you need to find a way based on your requirements and connect them. }
if you want to delete the text, you can just delete the run.
call the run's remove() method.
r.Remove();
More details about Runs and text object,
If you use the file as template, usually I will set some special properties on the Run element, so later, I can find them with more accuracy.
for example, inside the run loop, before checking its text, you can check the color first.
if( r.RunProperties.Highlight.Val == DocumentFormat.OpenXml.Wordprocessing.HighlightColorValues.Yellow )
{
string sText = r.InnerText ;
....
}
Hope it helps.
If you don't want the element any more then you can delete the whole element:
using (WordprocessingDocument doc = WordprocessingDocument.Open(memoryStream, true))
{
foreach (Text element in doc.MainDocumentPart.Document.Body.Descendants<Text>())
{
if (element.Text == "TextToRemove")
element.Remove();
}
}
Edit
If you're left with an empty line the chances are you have a Paragraph that contained the Text. In that case you want to remove the Paragraph instead in which case you can do:
if (element.Text == "TextToRemove")
element.Parent.Remove();
I don't think it's the paragraph element causing the empty line when removed.
Clients send over a template with an address block as:-
[address1]
[address2]
[city]
[town]
[state]
[zip]
The fields are populated from the database with the replace function, but if an address doesn't contain an [address2] value, that's what I need removing. If I remove the text, I'm still left with an empty line between [address1] and [city]. The [address2] field isn't in it's own paragraph.

Get the formatting of a table that a specific string of text exisits in and create a new table with the same formatting

Using OpenXML in C#, we need to:
Find a specific string of text on a Word document (this text will always exist in a table cell)
Get the formatting of the text and the table that the text exists in.
Create a new table with the same text and table formatting while pulling in text values for the cell from a nested List
This is the code that I currently have and the places I am not sure how do:
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(fileWordFile, true))
{
MainDocumentPart mainPart = wordDoc.MainDocumentPart;
Body body = mainPart.Document.Body;
IEnumerable paragraphs = body.Elements<Paragraph>();
Paragraph targetParagraph = null;
//Comment 1: Loop through paragraphs and search for a specific string of text in word document
foreach (Paragraph paragraph in paragraphs) {
if(paragraph.Elements<Run>().Any()) {
Run run = paragraph.Elements<Run>().First();
if(run.Elements<Text>().Any()) {
Text text = run.Elements<Text>().First();
if (text.Text.Equals("MY SEARCH STRING")) {
targetParagraph = paragraph;
// Comment 2: How can I get the formatting of the table that contains this text??
}
}
}
}
//Comment 3: Create table with same formatting as where the text was found
Table table1 = new Table();
TableProperties tableProperties1 = new TableProperties();
//Comment 4: How can I set these properties to be the same as the one found at "Comment 2"??
wordDoc.Close();
wordDoc.Dispose();
}
If you're looking for text elements that are inside a table cell, you can use a LINQ query to get there quickly without needing to use a heap of nested loops.
// Find the first text element matching the search string
// where the text is inside a table cell.
var textElement = body.Descendants<Text>()
.FirstOrDefault(t => t.Text == searchString &&
t.Ancestors<TableCell>().Any());
Once you have your match, the easiest way to duplicate the containing table with all its formatting and contents is simply to clone it.
if (textElement != null)
{
// get the table containing the matched text element and clone it
Table table = textElement.Ancestors<Table>().First();
Table tableCopy = (Table)table.CloneNode(deep: true);
// do stuff with copied table (see below)
}
After that, you can add things to the corresponding cell of the copied table. It's not entirely clear what you meant by "pulling in text values for the cell from a nested List" (what list? nested where?), so I'll just show a contrived example. (This code would replace the "do stuff" comment in the code above.)
// find the table cell containing the search string in the copied table
var targetCell = tableCopy.Descendants<Text>()
.First(t => t.InnerText == searchString)
.Ancestors<TableCell>()
.First();
// get the properties from the first paragraph in the target cell (so we can copy them)
var paraProps = targetCell.Descendants<ParagraphProperties>().First();
// now add new stuff to the target cell
List<string> stuffToAdd = new List<string> { "foo", "bar", "baz", "quux" };
foreach (string item in stuffToAdd)
{
// for each item, clone the paragraph properties, then add a new paragraph
var propsCopy = (ParagraphProperties)paraProps.CloneNode(deep: true);
targetCell.AppendChild(new Paragraph(propsCopy, new Run(new Text(item))));
}
Lastly, you need to add the copied table to the document somewhere or you won't see it. You don't say in your question where you would want this to appear, so I'll just put it at the end of the document. You can use methods like InsertAfter, InsertAt, InsertBefore, etc. to insert the table relative to other elements.
body.AppendChild(tableCopy);
Hope this helps.

How to set Excel "Print Titles" with OpenXML

How can I set the "Print Titles" property of a spreadsheet with OpenXML, to have a row show at the top of every printed page?
The property is directly saved in the SpreadsheetPrintingParts object, however, this doesn't appear to be fully integrated into OpenXML as of yet, and requires passing a base64 string in to the variable. (see here) The content of this string appears to be tied to the machine the file is opened on, which didn't work for my implementation - I wasn't able to create a non-corrupt file through SpreadsheetPrintingParts.FeedData().
Instead, I found this post which stated giving the row the defined name "Print_Titles" has the same effect. I was then able to create a defined name through OpenXML with the following code:
public void SetPrintTitleRows(int startRowIndex, int? endRowIndex = null)
{
var localSheetId = _localsheetId++; //LocalSheetIds are 0-indexed.
var definedName = new DefinedName
{
Name = "_xlnm.Print_Titles",
LocalSheetId = localSheetId,
Text = String.Format("\'{0}\'!${1}:${2}", _sheetName, startRowIndex, endRowIndex ?? startRowIndex)
};
if (_workbookPart.Workbook.DefinedNames == null)
{
var definedNamesCol = new DefinedNames();
_workbookPart.Workbook.Append(definedNamesCol);
}
_workbookPart.Workbook.DefinedNames.Append(definedName);
}
Points to note:
DefinedName.LocalSheetId is zero-indexed, as opposed to Sheet.Id which is 1-indexed
DefinedNames is once per workbook, but can contain multiple DefinedName objects for different sheets.

CRM2011 - Why are existing values being deleted when I add a new option set value using InsertOptionValueRequest

I'm trying to add new values to a MS Dynamics CRM option set in C# with InsertOptionValueRequest, and when I do, some of the existing option set values get deleted.
The code I am using is as follows:
ovRequest = new InsertOptionValueRequest
{
AttributeLogicalName = strOptionsetName,
EntityLogicalName = strEntityName,
Label = new Label(strLabel, LanguageCode)
};
_service.Execute(ovRequest);
I then publish entity with:
pxReq1 = new PublishXmlRequest { ParameterXml = String.Format("<importexportxml><entities><entity>{0}</entity></entities></importexportxml>", strEntityName) };
ospService.Execute(pxReq1);
I am finding this is happening both with Local Option Sets and Global Option Sets and can't see any pattern in the value being deleted. Am I doing something wrong or is this a bug in the SDK?
PS, can someone add a insertoptionvaluerequest tag to this, because I think that tag would be most relevant to this post.
I have found an answer to my question. MS Dynamics is not deleting existing values, it is overwriting the label on existing option set values. This is definitely a bug as the command being run is InsertOptionValueRequest and there is a separate UpdateOptionValueReqequest for updating values.
To work around it, manually set the Value when inserting the record instead of relying on the system to generate one for you:
ovRequest = new InsertOptionValueRequest
{
AttributeLogicalName = strOptionsetName,
EntityLogicalName = strEntityName,
Label = new Label(strLabel, LanguageCode),
Value = MyNewValue
};
_service.Execute(ovRequest);

Categories

Resources