Groups | Blog | Home
all groups > dotnet xml > january 2005 >

dotnet xml : Using XPath function lang() does not work in XPathNavigator


Alexander Gräf
1/5/2005 7:39:23 PM
Hello,

I'm stuck with a simple problem, for which I don't have a solution. I
basically have an XML file containing fragments of plain text and html, in
several languages:

<?xml version="1.0" encoding="UTF-8" ?>
<ms:Locales xmlns:ms="urn:myspace" xmlns="http://www.w3.org/1999/xhtml">
<ms:Locale id="EN" locale="en-US" xml:lang="EN">
<ms:Text name="LegalInformation">Legal Information</ms:Text>
<ms:Text name="Imprint">Imprint</ms:Text>
<ms:Text name="PrivacyPolicy">Privacy Policy</ms:Text>
</ms:Locale>
<ms:Locale id="DE" locale="de-DE" xml:lang="DE">
<ms:Text name="LegalInformation">Rechtlicher Hinweis</ms:Text>
<ms:Text name="Imprint">Impressum</ms:Text>
<ms:Text name="PrivacyPolicy">Datenschutz</ms:Text>
</ms:Locale>
</ms:Locales>

Now I have written some C# to query the xml, searching for the language and
the name:

public XPathNodeIterator Local(string Key, CultureInfo Culture)
{
// Load document
XmlDocument locales=new XmlDocument();
locales.Load("Locales.xml");
XmlNamespaceManager nsmanager=new XmlNamespaceManager(locales.NameTable);
nsmanager.AddNamespace("ms", "urn:myspace");

// Create navigator
XPathNavigator navigator=locales.CreateNavigator();

// Create and format search strings
const string
Search="/ms:Locales/ms:Locale[lang('{0}')]/ms:Text[@name='{1}']";
string Format=String.Format(Search,
Culture.TwoLetterISOLanguageName.ToUpper(), Key);

// Create expression from string with namespaces
XPathExpression expression=navigator.Compile(Format);
expression.SetContext(nsmanager);

// Return iterator
return navigator.Select(expression);
}

However, it does not work. It works if I replace one line into this:
const string
Search="/ms:Locales/ms:Locale[@xml:lang='{0}']/ms:Text[@name='{1}']";

I tried several things, and as a last check, I downloaded XML Spy from
Altova, loaded the Locales.xml and used the "Evaluate XPath" dialog to check
whats wrong:
/ms:Locales/ms:Locale[lang('DE')]/ms:Text[@name='Imprint']
This gives me - as expected - one ms:Text-node containing "Impressum".

I simply don't know what I am doing wrong. lang() seems to evaluate to false
in any case, because this will return both language nodes:

// Create and format search strings
const string
Search="/ms:Locales/ms:Locale[not(lang('{0}'))]/ms:Text[@name='{1}']";
string Format=String.Format(Search,
Culture.TwoLetterISOLanguageName.ToUpper(), Key);

Is this a bug in the .NET Framework? I'm using v1.1.4322 with Visual Studio
2003 running on a german OS.

Thank you in advance,
Alexander Gräf


Martin Honnen
1/6/2005 4:08:29 PM


[quoted text, click to view]


[quoted text, click to view]

I think case matters, at least in .NET's XSLT/XPath lang function so try
whether
Culture.TwoLetterISOLanguageName.ToLower()
improves things.


--

Martin Honnen
Alexander Gräf
1/6/2005 4:20:59 PM

"Martin Honnen" <mahotrash@yahoo.de> schrieb im Newsbeitrag
news:OVTqYGA9EHA.3708@TK2MSFTNGP14.phx.gbl...
[quoted text, click to view]

Thanks. Sometimes this are the small things that make the difference.
Curiously enough, because xml:lang is defined with upper case letters. I
never thought of using lower case for lang(), mainly because it simply works
with upper case in my XSL files. So either the XPath or the XSL
implementation is wrong. However, thanks a lot for this simple solution.

Regards, Alexander

Martin Honnen
1/6/2005 5:57:47 PM


[quoted text, click to view]

I think the XPath specification
<http://www.w3.org/TR/xpath#function-lang>
is pretty clear that comparison should ignore case so it looks like a
bug in .NET's XPath implementation.

--

Martin Honnen
AddThis Social Bookmark Button