Tuesday, June 24, 2008

Saving an XPathDocument or XmlDocument to a File in ASP.NET

Today I was working on a class that was returning an XPathDocument representation of an XML document and I needed to save it to a file. I switched the class to return an XmlDocument ... and the reason for that should be obvious from the two code samples below.

Here's how I saved an XPathDocument to an XML file:

// myItems[0] is from a generic List<XPathDocument> list
XPathDocument document = myItems[0];
// Feels like there should be an easier way to do this.
XPathNavigator documentNav = document.CreateNavigator();
XmlTextWriter writer = new XmlTextWriter(
Server.MapPath(temporaryFiles + "/" +
fileId + ".xml"), System.Text.Encoding.UTF8);
writer.Formatting = Formatting.Indented;
writer.Indentation = 3;
writer.WriteStartDocument();
writer.WriteNode(documentNav, true);
writer.WriteEndDocument();
writer.Close();

Now here's how I saved an XmlDocument to an XML file:

// myItems[0] is from a generic List<XmlDocument> list
XmlDocument document = myItems[0];
document.Save(
Server.MapPath(temporaryFiles + "/" + fileId + ".xml"));

Monday, June 23, 2008

Load an XML File from the File System into Textml with ASP.NET

I'm building an internal application that needs to load an XML file from the file system into a specific repository path in Textml Server. Here's the method I used within a ContentServer class I created.

The references to various this properties are set in the same class where I get the values from a configuration file for the staging and production servers.
public bool Publish(string fileUri)
{
try
{
ArrayList documents = new ArrayList(1);
IxiaClientServices IxiaCS = new IxiaClientServices();
IxiaServerServices IxiaSS = IxiaCS.ConnectServer(this.ContextServer);
IxiaDocBaseServices IxiaDS = IxiaSS.ConnectDocBase(this.ContextContainer);
IxiaDocumentServices ds = IxiaDS.DocumentServices;
IxiaDocument document = IxiaDocument.getInstance();
FileInfo file = new FileInfo(fileUri);

document.Name = file.Name;
document.MimeType = "text/xml";
document.Collection = this.ContextAdditionalName;
document.Content = IxiaDocument.MakeBinaryContent(file.FullName);

documents.Add(document);
IxiaTextmlServerError [] err = ds.SetDocuments(documents,
(int)IxiaDocumentServices.TextmlSetDocuments.TextmlAddDocument |
(int)IxiaDocumentServices.TextmlSetDocuments.TextmlReplaceDocument |
(int)IxiaDocumentServices.TextmlSetDocuments.TextmlIndexDocument,
TextmlDocumentType.TextmlDocument);

// If there is more than one item, and that first item is
// not null or empty, return false.
if (err.Length > 1 && !String.IsNullOrEmpty(err[0].ToString()))
{
// TODO: Log each in the EventViewer
return false;
}
else return true;
}
catch (Exception ex)
{
// TODO: Log in the EventViewer
return false;
}
}

I need to do the same into MarkLogic so I'll post that snippet here as soon as it's done.

Tuesday, June 17, 2008

Using the ASP.NET AdRotator Control for Text-Only Ads

Here's a pathetic little hack to leverage the ASP.NET AdRotator control to generate text-only ads.

In your ASPX page:

<asp:AdRotator
ID="AdRotator1"
AdvertisementFile="~/App_Data/DidYouKnow.config"
runat="server"
OnAdCreated="AdRotator1_CustomAdCreated"/>

<asp:HyperLink
ID="HyperLink1"
runat="server"
NavigateUrl="#"></asp:HyperLink>

In your code-behind page:

public void AdRotator1_CustomAdCreated(object sender, AdCreatedEventArgs e)
{
AdRotator1.Visible = false;
HyperLink1.Text = e.AlternateText;
HyperLink1.NavigateUrl = e.NavigateUrl;
}

In your XML file:

<?xml version="1.0" encoding="utf-8" ?>
<Advertisements>
<Ad>
<NavigateUrl>target.aspx</NavigateUrl>
<AlternateText>Did You Know Item 1</AlternateText>
</Ad>
<Ad>
<NavigateUrl>target.aspx</NavigateUrl>
<AlternateText>Did You Know Item 2</AlternateText>
</Ad>
<Ad>
<NavigateUrl>target.aspx</NavigateUrl>
<AlternateText>Did You Know Item 3</AlternateText>
</Ad>
</Advertisements>

Sunday, June 15, 2008

Getting Server and Other HTTP Information in a Class in an ASP.NET App

Another tidbit I can never remember when I need it. You're working on an ASP.NET website and you have a class that needs to access the Request or Response information, for example. Use HttpContext.Current as in the sample below.
_name = HttpContext.Current.Request.ServerVariables["SERVER_NAME"];

Wednesday, June 11, 2008

Removing Noise Words from a String with XQuery

MarkLogic doesn't offer a way to do stop words (a/k/a suppression lists a/k/a noise words) by default for various reasons -- and I didn't want to block them from being used in searches -- but I was asked to remove them from consideration when using hit highlighting. Here's the code I used to remove a fixed set of noise words from a user's search string.

define variable $NOISE_WORDS as xs:string*
{
(: \b is a word boundary. This catches beginning,
end, and middle of string matches on whole words. :)
('\bthe\b', '\bof\b', '\ban\b', '\bor\b',
'\bis\b', '\bon\b', '\bbut\b', '\ba\b')
}

define function remove-noise-words($string, $noise)
{
(: This is a recursive function. :)
if(not(empty($noise))) then
remove-noise-words(
replace($string, $noise[1], '', 'i'),
(: This passes along the noise words after
the one just evaluated. :)
$noise[position() > 1]
)
else normalize-space($string)
}

let $source-string1 := "The Tragedy of King Lear"
let $source-string2 := "The Tragedy OF King Lear These an"
let $source-string3 :=
"The Tragedy of the an of King Lear These of"
let $source-string4 := "The of an of"
(: Need to handle empty result if all noise words,
as in #4 above. :)
let $final :=
remove-noise-words($source-string1, $NOISE_WORDS)
return $final