XmlReader.ReadtoFollowing has state EndofFile why? - xmlreader

I've produced this code to read an xml file from a string, however it has problems. Notably the ReadToFollowing() method returns nothing. It seems to seek the whole xmlstring, then set the XMLReader state to the EndofFile. I'm very puzzled by this, ReadStartElement() works and the next element is read as "heading" as you'd expect.
Here's my code, my idea is to read through the xml pulling out the fields I require;
List<string> contentfields = new List<string>() { "heading", "shortblurb", "description" };
string xml = #"<filemeta filetype='Audio'><heading>Fatigue & Tiredness</heading><shortblurb>shortblurb</shortblurb><description /><Comments /><AlbumTitle /><TrackNumber /><ArtistName /><Year /><Genre /><TrackTitle /></filemeta>";
using (XmlReader reader = XmlReader.Create(new StringReader(xml)))
{
reader.ReadStartElement("filemeta");
foreach (String field_str in contentfields)
{
reader.ReadToFollowing(field_str);
if (reader.Name.ToString() == field_str)
{
Console.WriteLine(field_str + " " + reader.ReadElementContentAsString());
}
}
}
Console.ReadKey();

That's because reader.ReadStartElement("filemeta"); will position the reader on the xml tag heading.
ReadToFollowing will then do 1 read (reading past your heading tag) and then start to seek an element with the name heading. As you just read past it, ReadToFollowing will not find it anymore and read to the end of the file.
If you want to avoid this, change your code like this :
List<string> contentfields = new List<string>() { "heading", "shortblurb", "description" };
string xml = #"<filemeta filetype='Audio'><heading>Fatigue & Tiredness</heading><shortblurb>shortblurb</shortblurb><description /><Comments /><AlbumTitle /><TrackNumber /><ArtistName /><Year /><Genre /><TrackTitle /></filemeta>";
using (XmlReader reader = XmlReader.Create(new StringReader(xml)))
{
reader.ReadStartElement("filemeta");
foreach (String field_str in contentfields)
{
if (reader.Name.ToString() != field_str)
{
reader.ReadToFollowing(field_str);
}
//still keep this if because we could have reached the end of the xml document
if (reader.Name == field_str)
{
Console.WriteLine(field_str + " " + reader.ReadElementContentAsString());
}
}
}
Console.ReadKey();

Related

How to check for a specific value in List<T> foreach loop

Need help checking for a specific value in List<T> foreach loop. If there is specific value then display a specific string value.
For example how do I…
If (value.something_2 == "Null")
{
value.something_2 == ".";
}
Elseif (value.something_2 == " ")
{
value.something_2 == "0";
}
How would I incorporate the above example within the “foreach” loop?
See code below.
protected void MyReport(string filename, IMyRepository repository)
{
using (FileStream fileStream = new FileStream(Server.MapPath(#"~/Includes/") + filename, FileMode.Create))
{
using (StreamWriter writer = new StreamWriter(fileStream))
{
List<Report> _report = repository.GetMyReport().ToList();
foreach (var value in _report)
{
String row01 = String.Format("{0, -10}{1, 23}{2, 120}{3, 8}",
value.somthing_1,
values.something_2,
value.something_3);
String row02 = String.Format("{0, -10}{1, 23}{2, 120}{3, 8}",
value.somthing_4,
values.something_5,
value.something_6);
Writer.WriteLine(row01);
Writer.WriteLine(row02);
}
}
writer.Close();
}
}
There is no clever built-in String.Format that you can do for this if that's what you have in mind. However, the compiler has some tricks that can reduce the amount of code you need to write e.g.
// if it's null, assign it to "."
var s2 = value.something_2 ?? ".";
// it can never be null here, so if there is whitespace default to "0"
value.something_2 = String.IsNullOrWhitespace(s2) ? "0" : s2;
If I'm understanding what you're saying, it might be easier just to have another function returning the (possibly) modified string and just pass each of your values into it, inline.
Sting row01 = String.Format("{0, -10}{1, 23}{2, 120}{3, 8}", myFunc(value.somthing_1), myFunc(values.something_2), myFunc(value.something_3));
and then have this in the same class
private string myFunc(string something){
if (something == “Null”){
return “.“;
} else if (something == “ “) {
return “0”;
} else {
return something;
}
}

Custom sort file name string array

I'm retrieving a string array of files and I would like to custom sort them by a substring in the file name...using C# **.NET 3.5. Below is what I am working with.
<% string[] files = System.IO.Directory.GetFiles("...path..." + pageName + "\\reference\\");
files = String.Join(",", files).Replace("...path...", "").Replace("\\reference\\", "").Replace(pageName, "").Split(new Char[] { ',' });
foreach (String item in files)
{
Response.Write("<a href=" + pageName + "/reference/" + System.IO.Path.GetFileName(item) + " target='_blank'>" + item.Replace("_", " ").Replace(".pdf", " ") + "</a>");
}
%>
I'm a C# noob, and I don't know where to go from here. Basically, I'm looking for a substring in the file name to determine the order (e.g., "index","reference","list"; where any file including the string "index" would be listed first). Perhaps there is a better way to do it. Any help would be appreciated.
You can use Linq to order the array by the filenames. In general, use the Path class if you're working with paths.
string fullPath = Path.Combine(directory, pageName, "reference");
var filePaths = Directory.EnumerateFiles(fullPath, "*.*", SearchOption.TopDirectoryOnly)
.Select(fp => new{ FullPath = fp, FileName=Path.GetFileName(fp) })
.OrderByDescending(x => x.FileName.IndexOf("index", StringComparison.OrdinalIgnoreCase) >= 0)
.ThenByDescending(x => x.FileName.IndexOf("reference", StringComparison.OrdinalIgnoreCase) >= 0)
.ThenByDescending(x => x.FileName.IndexOf("list", StringComparison.OrdinalIgnoreCase) >= 0)
.ThenBy(x=> x.FileName)
.Select(x => x.FullPath);
foreach(string filePath in filePaths)
;// ...
If you don't want to compare case-insensitively (so that "index" and "Index" are considered the same) use String.Contains instead of String.IndexOf + StringComparison.OrdinalIgnoreCase.
Here's an easy way I use when I run into this problem.
Define the order of the substrings in a list. Then for each item, check to see whats the first thing that contains that item. Then sort by the order of the substring in the list.
public class SubStringSorter : IComparer<string>
{
public int Compare(string x, string y)
{
var source = x.ToLowerInvariant();
var target = y.ToLowerInvariant();
var types = new List<string> { "base", "data", "model", "services", "interceptor", "controllers", "directives", "filters", "app", "tests", "unittests" };
var sourceType = types.IndexOf(types.FirstOrDefault(source.Contains));
var targetType = types.IndexOf(types.FirstOrDefault(target.Contains));
return sourceType.CompareTo(targetType);
}
}
To sort your files, do something like
var list = new List<string>{ "baseFile", "servicesFile", "this ModElstuff" };
list.Sort(new SubStringSorter());
And the output
You could even go one step further and give the substring sorter the list as part of its constructor so you can re-use the substring sort order with other items. The example I posted tests if the string exists in any context, but if you are more interested in it starting with a string you can do that too.

Magento 1.7 SOAP v2 Api - Creating products with additional attributes

I have set up a web shop with Magento version 1.7 and my next task is to import products by using the v2 Soap api. So far, everything seems to work except for one thing: All the custom attributes of the created products remain empty. Everything else works fine - the name, sku, price, description and so on.
My script runs with asp.net so I don't have any PHP code but I think it looks more or less similar. Here is a snippet that I use where the attributes are assigned to a product:
dim create as new catalogProductCreateEntity
create.name = "Test"
create.price = "11.1100"
create.description = "test description"
dim additional(0) as associativeEntity
dim attribute as new associativeEntity
attribute.key = "manufacturer"
attribute.key = "xyz"
additional(0) = attribute
create.additional_attributes = additional
In this case, a simple text field should receive the value "xyz".
I use the very same procedure in other Magento stores that I have set up in the past and it works just fine. The only difference is that these shops use Magento version 1.5.
Could this be a bug in the api?
"xyz" needs to go into .value of the associativeEntity:
dim additional(0) as associativeEntity
dim attribute as new associativeEntity
attribute.key = "manufacturer"
attribute.value = "xyz"
additional(0) = attribute
Hope this helps.
i have successfully done this in C#, below is the code
private void getAdditionalAttributes()
{
string skuNumber="S00001";
MagentoService mservice = new MagentoService();
string sessionkey = "";
try
{
sessionkey = mservice.login("apiuser", "apipassword");
}
catch (Exception exp)
{
//Error
}
try
{
catalogProductRequestAttributes fetchattrib = new catalogProductRequestAttributes();
// it will only populate the attributes that you ask for
fetchattrib.attributes = new string[] { "name", "description", "short_description" };
// Additional Attribute
fetchattrib.additional_attributes = new string[] { "ismemo","color" };
catalogProductReturnEntity prod = MagentoConnectivity.magService.catalogProductInfo(sessionkey, skuNumber, "", fetchattrib, "sku");
foreach (var item in prod.additional_attributes)
{
MessageBox.Show("=> Key: " + item.key + "\t Attribute Value=" + item.value + "\n");
}
}
catch (Exception exp)
{
MessageBox.Show("=> Exception in getting Additional Attributes \n" + exp.Message + "\n");
return;
}
}

How to make simple dicitonary J2ME

I am beginner in JavaME. I'd like to make simple dicitionary. The source data is placed on "data.txt" file in "res" directory. The structure is like this:
#apple=kind of fruit;
#spinach=kind of vegetable;
The flow is so simple. User enters word that he want to search in a text field, e.g "apple", system take the user input, read the "data.txt", search the matched word in it, take corresponding word, and display it to another textfield/textbox.
I've managed to read whole "data.txt" using this code..
private String readDataText() {
InputStream is = getClass().getResourceAsStream("data.txt");
try {
StringBuffer sb = new StringBuffer();
int chr, i=0;
while ((chr = is.read()) != -1)
sb.append((char) chr);
return sb.toString();
}
catch (Exception e) {
}
return null;
}
but I still dont know how to split it, find the matched word with the user input and take corresponding word. Hope somebody willing to share his/her knowledge to help me..
Basically you want something like this:
private String readDataText() {
InputStream is = getClass().getResourceAsStream("data.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
try {
while ((line = br.readLine()) != null)
{
String[] split = line.split("=");
if (split[0].equals("#someFruit"))
return split[1];
}
}
catch (Exception e) {}
return null;
}
Read the line using a BufferedReader, no need to handle single chars.
Split the line by the = token
Check if the key in the dictionary is the wanted key, if so, return the value.

How do I convert a .docx to html using asp.net?

Word 2007 saves its documents in .docx format which is really a zip file with a bunch of stuff in it including an xml file with the document.
I want to be able to take a .docx file and drop it into a folder in my asp.net web app and have the code open the .docx file and render the (xml part of the) document as a web page.
I've been searching the web for more information on this but so far haven't found much. My questions are:
Would you (a) use XSLT to transform the XML to HTML, or (b) use xml manipulation libraries in .net (such as XDocument and XElement in 3.5) to convert to HTML or (c) other?
Do you know of any open source libraries/projects that have done this that I could use as a starting point?
Thanks!
Try this post? I don't know but might be what you are looking for.
I wrote mammoth.js, which is a JavaScript library that converts docx files to HTML. If you want to do the rendering server-side in .NET, there is also a .NET version of Mammoth available on NuGet.
Mammoth tries to produce clean HTML by looking at semantic information -- for instance, mapping paragraph styles in Word (such as Heading 1) to appropriate tags and style in HTML/CSS (such as <h1>). If you want something that produces an exact visual copy, then Mammoth probably isn't for you. If you have something that's already well-structured and want to convert that to tidy HTML, Mammoth might do the trick.
Word 2007 has an API that you can use to convert to HTML. Here's a post that talks about it http://msdn.microsoft.com/en-us/magazine/cc163526.aspx. You can find documentation around the API, but I remember that there is a convert to HTML function in the API.
This code will helps to convert .docx file to text
function read_file_docx($filename){
$striped_content = '';
$content = '';
if(!$filename || !file_exists($filename)) { echo "sucess";}else{ echo "not sucess";}
$zip = zip_open($filename);
if (!$zip || is_numeric($zip)) return false;
while ($zip_entry = zip_read($zip)) {
if (zip_entry_open($zip, $zip_entry) == FALSE) continue;
if (zip_entry_name($zip_entry) != "word/document.xml") continue;
$content .= zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
zip_entry_close($zip_entry);
}// end while
zip_close($zip);
//echo $content;
//echo "<hr>";
//file_put_contents('1.xml', $content);
$content = str_replace('</w:r></w:p></w:tc><w:tc>', " ", $content);
$content = str_replace('</w:r></w:p>', "\r\n", $content);
//header("Content-Type: plain/text");
$striped_content = strip_tags($content);
$striped_content = preg_replace("/[^a-zA-Z0-9\s\,\.\-\n\r\t#\/\_\(\)]/","",$striped_content);
echo nl2br($striped_content);
}
I'm using Interop. It is somewhat problamatic but works fine in most of the case.
using System.Runtime.InteropServices;
using Microsoft.Office.Interop.Word;
This one returns the list of html converted documents' path
public List<string> GetHelpDocuments()
{
List<string> lstHtmlDocuments = new List<string>();
foreach (string _sourceFilePath in Directory.GetFiles(""))
{
string[] validextentions = { ".doc", ".docx" };
if (validextentions.Contains(System.IO.Path.GetExtension(_sourceFilePath)))
{
sourceFilePath = _sourceFilePath;
destinationFilePath = _sourceFilePath.Replace(System.IO.Path.GetExtension(_sourceFilePath), ".html");
if (System.IO.File.Exists(sourceFilePath))
{
//checking if the HTML format of the file already exists. if it does then is it the latest one?
if (System.IO.File.Exists(destinationFilePath))
{
if (System.IO.File.GetCreationTime(destinationFilePath) != System.IO.File.GetCreationTime(sourceFilePath))
{
System.IO.File.Delete(destinationFilePath);
ConvertToHTML();
}
}
else
{
ConvertToHTML();
}
lstHtmlDocuments.Add(destinationFilePath);
}
}
}
return lstHtmlDocuments;
}
And this one to convert doc to html.
private void ConvertToHtml()
{
IsError = false;
if (System.IO.File.Exists(sourceFilePath))
{
Microsoft.Office.Interop.Word.Application docApp = null;
string strExtension = System.IO.Path.GetExtension(sourceFilePath);
try
{
docApp = new Microsoft.Office.Interop.Word.Application();
docApp.Visible = true;
docApp.DisplayAlerts = WdAlertLevel.wdAlertsNone;
object fileFormat = WdSaveFormat.wdFormatHTML;
docApp.Application.Visible = true;
var doc = docApp.Documents.Open(sourceFilePath);
doc.SaveAs2(destinationFilePath, fileFormat);
}
catch
{
IsError = true;
}
finally
{
try
{
docApp.Quit(SaveChanges: false);
}
catch { }
finally
{
Process[] wProcess = Process.GetProcessesByName("WINWORD");
foreach (Process p in wProcess)
{
p.Kill();
}
}
Marshal.ReleaseComObject(docApp);
docApp = null;
GC.Collect();
}
}
}
The killing of the word is not fun, but can't let it hanging there and block others, right?
In the web/html i render html to a iframe.
There is a dropdown which contains the list of help documents. Value is the path to the html version of it and text is name of the document.
private void BindHelpContents()
{
List<string> lstHelpDocuments = new List<string>();
HelpDocuments hDoc = new HelpDocuments(Server.MapPath("~/HelpDocx/docx/"));
lstHelpDocuments = hDoc.GetHelpDocuments();
int index = 1;
ddlHelpDocuments.Items.Insert(0, new ListItem { Value = "0", Text = "---Select Document---", Selected = true });
foreach (string strHelpDocument in lstHelpDocuments)
{
ddlHelpDocuments.Items.Insert(index, new ListItem { Value = strHelpDocument, Text = strHelpDocument.Split('\\')[strHelpDocument.Split('\\').Length - 1].Replace(".html", "") });
index++;
}
FetchDocuments();
}
on selected index changed, it is renedred to frame
protected void RenderHelpContents(object sender, EventArgs e)
{
try
{
if (ddlHelpDocuments.SelectedValue == "0") return;
string strHtml = ddlHelpDocuments.SelectedValue;
string newaspxpage = strHtml.Replace(Server.MapPath("~/"), "~/");
string pageVirtualPath = VirtualPathUtility.ToAbsolute(newaspxpage);//
documentholder.Attributes["src"] = pageVirtualPath;
}
catch
{
lblGError.Text = "Selected document doesn't exist, please refresh the page and try again. If that doesn't help, please contact Support";
}
}

Resources