Best xml questions in December 2011

What type of collection should I use?

7 votes

I have approximately 10,000 records. Each records has 2 fields: one field is a string up to 300 characters in length and the other field is a decimal value. This is like a product catalog with product names and the price of each product.

What I need to do is allow the user to type any word and display all products containing that word together with their prices in a listbox. That's all.

  1. What type of collection is best for this scenario?
  2. If I need to sort based on either product name or price, will the choice still be the same?

Right now I am using an XML file, but I thought using a collection so that I can embed all the values in the code is simpler. Thanks for your suggestions.

A Dictionary will do the job. However, if you are doing rapid partial matches (e.g. search as the user types) you may get better performance by creating multiple keys which point to the same item. For example, the word "Apple" could be located with "Ap", "App", "Appl", and "Apple".

I have used this approach on a similar number of records with very good results. I have turned my 10K source items into about 50K unique keys. Each of these Dictionary entries points to a list containing references to all matches for that term. You can then search this much smaller list more efficiently. Despite the large number of lists this creates, the memory footprint is quite reasonable.

You can also make up your own keys if desired to redirect common misspellings or point to related items. This also eliminates most of the issues with unique keys because each key points to a list. A single item may be classified by each of the words in its name; this is extremely useful if you have long product names with multiple words in it. When classifying your items, each word in the name can be mapped to one or more keys.

I should also point out that building and classifying 10K items shouldn't take long if done correctly (couple hundred milliseconds is reasonable). The results can be cached for as long as you want using Application, Cache, or static members.

To summarize, the resulting structure is a Dictionary<string, List<T>> where the string is a short (2-6 characters works well) but unique key. Each key points to a List<T> (or other collection, if you are so inclined) of items which match that key. When a search is performed, you locate the key which matches the term provided by the user. Depending on the length of your keys, you may truncate the user's search to your maximum key length. After locating the correct child collection, you then search that collection for a complete or partial match using whatever methodology you wish.

Lastly, you may wish to create a lightweight structure for each item in the list so that you can store additional information about the item. For example, you might create a small Product class which stores the name, price, department, and popularity of the product. This can help you refine the results you show to the user.

All-in-all, you can perform intelligent, detailed, fuzzy searches in real-time.

How to parse an XML file containing BOM?

6 votes

I want to parse an XML file from URL using JDOM. But when trying this:

SAXBuilder builder = new SAXBuilder();
builder.build(aUrl);

I get this exception:

Invalid byte 1 of 1-byte UTF-8 sequence.

I thought this might be the BOM issue. So I checked the source and saw the BOM in the beginning of the file. I tried reading from URL using aUrl.openStream() and removing the BOM with Commons IO BOMInputStream. But to my surprise it didn't detect any BOM. I tried reading from the stream and writing to a local file and parse the local file. I set all the encodings for InputStreamReader and OutputStreamWriter to UTF8 but when I opened the file it had crazy characters.

I thought the problem is with the source URL encoding. But when I open the URL in browser and save the XML in a file and read that file through the process I described above, everything works fine.

I appreciate any help on the possible cause of this issue.

That HTTP server is sending the content in GZIPped form (Content-Encoding: gzip; see http://en.wikipedia.org/wiki/HTTP_compression if you don't know what that means), so you need to wrap aUrl.openStream() in a GZIPInputStream that will decompress it for you. For example:

builder.build(new GZIPInputStream(aUrl.openStream()));

Edited to add, based on the follow-up comment: If you don't know in advance whether the URL will be GZIPped, you can write something like this:

private InputStream openStream(final URL url) throws IOException
{
    final URLConnection cxn = url.openConnection();
    final String contentEncoding = cxn.getContentEncoding();
    if(contentEncoding == null)
        return cxn.getInputStream();
    else if(contentEncoding.equalsIgnoreCase("gzip")
               || contentEncoding.equalsIgnoreCase("x-gzip"))
        return new GZIPInputStream(cxn.getInputStream());
    else
        throw new IOException("Unexpected content-encoding: " + contentEncoding);
}

(warning: not tested) and then use:

builder.build(openStream(aUrl.openStream()));

. This is basically equivalent to the above — aUrl.openStream() is explicitly documented to be a shorthand for aUrl.openConnection().getInputStream() — except that it examines the Content-Encoding header before deciding whether to wrap the stream in a GZIPInputStream.

See the documentation for java.net.URLConnection.

rss read iphone/ipad app

6 votes

I have an error while reading XML files for my iPhone app. I have a new feature on my iPhone app that reads my RSS feed. Everything looks good by but I have this issue:

Error while loading rss. Please check your Internet connection

Here's my code:

- (BOOL) readRSS {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    [[NSURLCache sharedURLCache] setMemoryCapacity:0];
    [[NSURLCache sharedURLCache] setDiskCapacity:0];
    BOOL success = NO;
    NSXMLParser *parser = nil;
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://rss.domain.com/%@.xml", self.currentPage]];
    parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
    [parser setDelegate:self];
    [parser setShouldProcessNamespaces:NO];
    [parser setShouldReportNamespacePrefixes:NO];
    [parser setShouldResolveExternalEntities:NO];
    success = [parser parse];
    [parser release];
    [pool drain];
    return success;
}

Then I have this code:

- (void) cleartbl:(NSInteger)type {
    [[[self rssParser] rssItems] removeAllObjects];
    [_tableView reloadData];
    if(type == 1) {
        UIAlertView *alert = [[UIAlertView alloc] 
                          initWithTitle:@"RSS Feed" 
                          message:@"Error while loading rss. Please check your Internet connection."
                          delegate:nil 
                          cancelButtonTitle:@"OK" 
                          otherButtonTitles: nil];
        [alert show];   
        [alert release];
    }

Then i assign:

if([elementName isEqualToString:@"title"]){
    self.currentItem.title = self.currentItemValue;
}

What is my issue, am I missing something?

The code provided looks good for me, what I would do first is to check if your RSS is valid. I think you have an RSS issue here. You can use the RSS Validation to make sure everything looks good.

I would recommend to sanitize your RSS, keep it very simple, if you only want to display news or articles use letters and numbers in your text and use SEO friendly URLs.

This will simplify the data you are loading from your app and avoid errors like special characters.

Try with a simple RSS with one entry to start and you will see if your code has errors.

Are blank child nodes of any use to XML parsers?

6 votes

Why oh why do we have to have the notion of blank XML nodes? What benefit do they bring to the alchemy we have come to know as XML parsing?

A simple example here with Perl's XML::LibXML:

use strict;
use warnings;
use feature 'say';
use XML::LibXML;

my $xml = XML::LibXML->load_xml( string => <<'XMLDOC' );
<alphabet>
 <child name='alpha'/>
 <child name='bravo'/>
 <child name='charlie'/>
 <child name='delta'/>
 <child name='echo'/>
</alphabet>
XMLDOC

my ( $parent ) = $xml->findnodes( '/alphabet' );

my @all_kids  = $parent->childNodes;
my @real_kids = $parent->nonBlankChildNodes;

say 'All kids : ', scalar @all_kids;   # '11'
say 'Real kids : ', scalar @real_kids; # '5' => 6 blank child nodes

What puzzles me is that the parser makes a distinction between retrieving all child nodes and only non-blank ones.

It would seem then that there must be at least one sane use for these blank nodes. It would be interesting to know exactly what those uses are.

Consider this case from HTML:

<div><b>hello</b><i>world</i></div>

vs this one:

<div>
    <b>hello</b>
    <i>world</i>
</div>

In the first example, there are no whitespace nodes, and the rendering engine will not place a space between helloworld. In the second example, since there is a whitespace node between the textnodes, it will come out as hello world.

You need to know the whitespace nodes are there, since some XML languages will care about their placement.

Fast Natural Sort for Large XML File in Browser?

5 votes

I have a problem right now that is the result of current limitations on a server our team does not control.

We have a job that should have be done by database but we're forced to use a XML file and parse it using Javascript/jQuery. We don't even have write access for our scripts (only through our FTP account)... we don't like to talk about it but that's what we got.

The problem, as a result of those limitations, is that we need to parse a large XML file that's around 500kb, with 1700-ish records of document name/number/url.

The number is pretty complex, such as "31-2b-1029E", mixed with stuff like "T2315342".

So, I have figured that I need to use something called "Natural Sort" (thank you stackoverflow).

Anyways I tried using this script here:

/*
 * Reference: http://www.overset.com/2008/09/01/javascript-natural-sort-algorithm/
 * Natural Sort algorithm for Javascript - Version 0.6 - Released under MIT license
 * Author: Jim Palmer (based on chunking idea from Dave Koelle)
 * Contributors: Mike Grier (mgrier.com), Clint Priest, Kyle Adams, guillermo
 */
function naturalSort (a, b) {
    var re = /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi,
        sre = /(^[ ]*|[ ]*$)/g,
        dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,
        hre = /^0x[0-9a-f]+$/i,
        ore = /^0/,
        // convert all to strings and trim()
        x = a.toString().replace(sre, '') || '',
        y = b.toString().replace(sre, '') || '',
        // chunk/tokenize
        xN = x.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),
        yN = y.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),
        // numeric, hex or date detection
        xD = parseInt(x.match(hre)) || (xN.length != 1 && x.match(dre) && Date.parse(x)),
        yD = parseInt(y.match(hre)) || xD && y.match(dre) && Date.parse(y) || null;
    // first try and sort Hex codes or Dates
    if (yD)
        if ( xD < yD ) return -1;
        else if ( xD > yD ) return 1;
    // natural sorting through split numeric strings and default strings
    for(var cLoc=0, numS=Math.max(xN.length, yN.length); cLoc < numS; cLoc++) {
        // find floats not starting with '0', string or 0 if not defined (Clint Priest)
        oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0;
        oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0;
        // handle numeric vs string comparison - number < string - (Kyle Adams)
        if (isNaN(oFxNcL) !== isNaN(oFyNcL)) return (isNaN(oFxNcL)) ? 1 : -1; 
        // rely on string comparison if different types - i.e. '02' < 2 != '02' < '2'
        else if (typeof oFxNcL !== typeof oFyNcL) {
            oFxNcL += ''; 
            oFyNcL += ''; 
        }
        if (oFxNcL < oFyNcL) return -1;
        if (oFxNcL > oFyNcL) return 1;
    }
    return 0;
}

And applied using:

// Natural Sort (disabled because it is super freaking slow.... need xsl transform sorting instead)
var sortedSet = $(data).children("documents").children("document").sort(function(a, b) {
    return naturalSort($(a).children('index').text(), $(b).children('index').text());
});

This works fine on our other, smaller XML file, but for the giant 500kb-ish file Safari (v4) just plainly hangs for up to a few minutes to sort this through, while Firefox (latest) takes around 10 second to process (still not good, but at least sane).

I also found this other smaller/lighter script called Alphanum:

function alphanum(a, b) {
  function chunkify(t) {
    var tz = [], x = 0, y = -1, n = 0, i, j;

    while (i = (j = t.charAt(x++)).charCodeAt(0)) {
      var m = (i == 46 || (i >=48 && i <= 57));
      if (m !== n) {
        tz[++y] = "";
        n = m;
      }
      tz[y] += j;
    }
    return tz;
  }

  var aa = chunkify(a);
  var bb = chunkify(b);

  for (x = 0; aa[x] && bb[x]; x++) {
    if (aa[x] !== bb[x]) {
      var c = Number(aa[x]), d = Number(bb[x]);
      if (c == aa[x] && d == bb[x]) {
        return c - d;
      } else return (aa[x] > bb[x]) ? 1 : -1;
    }
  }
  return aa.length - bb.length;
}

This runs faster for Safari, but is still locks up the browser for a minute or so.

I did some research, and it seems that a few people recommended using XSL to sort the XML entries, which apparently is much faster due to it's being built into the browser instead of running on top of JavaScript.

There's apparently several different implementations, with Sarissa getting getting mentioned several times, the sourceforge page seems to indicate that the last update occured back in 2011-06-22.

There's also other choices such as xslt.js

My question is:

  1. Is XSL the best sorting option for this particular problem?
  2. If so how can I use XSL to do Natural Sort? (url to resources?)
  3. If yes to both questions, which library should I use for the best compatibility and speed?
  4. If XSL is not the best choice, then which one is?

Thanks for looking at my problem.

Good question, +1.

Here is an XSLT 1.0 solution (there is an XSLT 2.0 solution that is much simpler and easier to write and is probably more efficient, however none of the 5 major browsers comes with an XSLT 2.0 processor):

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common" exclude-result-prefixes="xml">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:variable name="vDigits" select="'0123456789'"/>

 <xsl:variable name="vPadding" select=
 "'                    '"/>

 <xsl:variable name="vMaxNumLength"
      select="string-length($vPadding)"/>

 <xsl:template match="/">
  <xsl:variable name="vrtfPass1">
   <t>
    <xsl:apply-templates/>
   </t>
  </xsl:variable>

  <xsl:variable name="vPass1" select="ext:node-set($vrtfPass1)"/>

  <t>
    <xsl:for-each select="$vPass1/*/*">
     <xsl:sort select="@sortMe"/>

     <xsl:copy>
      <xsl:value-of select="."/>
     </xsl:copy>
    </xsl:for-each>
  </t>
 </xsl:template>

 <xsl:template match="str">
   <str>
    <xsl:apply-templates select="text()" mode="normalize"/>
    <xsl:copy-of select="text()"/>
   </str>
 </xsl:template>

 <xsl:template match="text()" mode="normalize" name="normalize">
  <xsl:param name="pText" select="."/>
  <xsl:param name="pAccum" select="''"/>

  <xsl:choose>
   <xsl:when test="not(string-length($pText) >0)">
     <xsl:attribute name="sortMe">
       <xsl:value-of select="$pAccum"/>
     </xsl:attribute>
   </xsl:when>
   <xsl:otherwise>
    <xsl:variable name="vChar1" select="substring($pText,1,1)"/>

    <xsl:choose>
     <xsl:when test="not(contains($vDigits,$vChar1))">
       <xsl:variable name="vDig1" select=
       "substring(translate($pText,
                            translate($pText, $vDigits, ''),
                            ''
                            ),
                  1,1)"/>
       <xsl:variable name="vDig">
        <xsl:choose>
         <xsl:when test="string-length($vDig1)">
          <xsl:value-of select="$vDig1"/>
         </xsl:when>
         <xsl:otherwise>0</xsl:otherwise>
        </xsl:choose>
       </xsl:variable>

       <xsl:variable name="vNewText" select=
        "substring-before(concat($pText,$vDig), $vDig)"/>

       <xsl:call-template name="normalize">
        <xsl:with-param name="pText" select=
         "substring($pText, string-length($vNewText)+1)"/>
        <xsl:with-param name="pAccum" select=
        "concat($pAccum, $vNewText)"/>
       </xsl:call-template>
     </xsl:when>

     <xsl:otherwise>
      <xsl:variable name="vNonDig1" select=
      "substring(translate($pText, $vDigits, ''),1,1)"/>

      <xsl:variable name="vNonDig">
        <xsl:choose>
         <xsl:when test="string-length($vNonDig1)">
          <xsl:value-of select="$vNonDig1"/>
         </xsl:when>
         <xsl:otherwise>Z</xsl:otherwise>
        </xsl:choose>
      </xsl:variable>

      <xsl:variable name="vNum" select=
           "substring-before(concat($pText,'Z'),$vNonDig)"/>

      <xsl:variable name="vNumLength" select=
       "string-length($vNum)"/>

      <xsl:variable name="vNewText" select=
       "concat(substring($vPadding,
                         1,
                         $vMaxNumLength -$vNumLength),
               $vNum
               )"/>

       <xsl:call-template name="normalize">
        <xsl:with-param name="pText" select=
         "substring($pText, $vNumLength +1)"/>
        <xsl:with-param name="pAccum" select=
        "concat($pAccum, $vNewText)"/>
       </xsl:call-template>
     </xsl:otherwise>
    </xsl:choose>
   </xsl:otherwise>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

when this transformation is applied on the XML document below:

<t>
 <str>Allegia 6R Clasteron</str>
 <str>200X Radonius</str>
 <str>Xiph Xlater 10000</str>
 <str>1000X Radonius Maximus</str>
 <str>Callisto Morphamax 6000 SE</str>
 <str>10X Radonius</str>
 <str>20X Radonius</str>
 <str>30X Radonius</str>
 <str>20X Radonius Prime</str>
 <str>40X Radonius</str>
 <str>Allegia 50 Clasteron</str>
 <str>Allegia 500 Clasteron</str>
 <str>Allegia 50B Clasteron</str>
 <str>Allegia 51 Clasteron</str>
 <str>Alpha 100</str>
 <str>Alpha 2</str>
 <str>Alpha 200</str>
 <str>Alpha 2A</str>
 <str>Alpha 2A-8000</str>
 <str>Alpha 2A-900</str>
 <str>Callisto Morphamax</str>
 <str>Callisto Morphamax 500</str>
 <str>Callisto Morphamax 5000</str>
 <str>Callisto Morphamax 600</str>
 <str>Callisto Morphamax 6000 SE2</str>
 <str>Callisto Morphamax 700</str>
 <str>Callisto Morphamax 7000</str>
 <str>Xiph Xlater 2000</str>
 <str>Xiph Xlater 300</str>
 <str>Xiph Xlater 40</str>
 <str>Xiph Xlater 5</str>
 <str>Xiph Xlater 50</str>
 <str>Xiph Xlater 500</str>
 <str>Xiph Xlater 5000</str>
 <str>Xiph Xlater 58</str>
</t>

the wanted, correctly "natural-sorted" result is produced:

<t>
   <str>10X Radonius</str>
   <str>20X Radonius</str>
   <str>20X Radonius Prime</str>
   <str>30X Radonius</str>
   <str>40X Radonius</str>
   <str>200X Radonius</str>
   <str>1000X Radonius Maximus</str>
   <str>Allegia 6R Clasteron</str>
   <str>Allegia 50 Clasteron</str>
   <str>Allegia 50B Clasteron</str>
   <str>Allegia 51 Clasteron</str>
   <str>Allegia 500 Clasteron</str>
   <str>Alpha 2</str>
   <str>Alpha 2A</str>
   <str>Alpha 2A-900</str>
   <str>Alpha 2A-8000</str>
   <str>Alpha 100</str>
   <str>Alpha 200</str>
   <str>Callisto Morphamax</str>
   <str>Callisto Morphamax 500</str>
   <str>Callisto Morphamax 600</str>
   <str>Callisto Morphamax 700</str>
   <str>Callisto Morphamax 5000</str>
   <str>Callisto Morphamax 6000 SE</str>
   <str>Callisto Morphamax 6000 SE2</str>
   <str>Callisto Morphamax 7000</str>
   <str>Xiph Xlater 5</str>
   <str>Xiph Xlater 40</str>
   <str>Xiph Xlater 50</str>
   <str>Xiph Xlater 58</str>
   <str>Xiph Xlater 300</str>
   <str>Xiph Xlater 500</str>
   <str>Xiph Xlater 2000</str>
   <str>Xiph Xlater 5000</str>
   <str>Xiph Xlater 10000</str>
</t>

Important assumption: This solution supposes that no number would have more than 40 digits. While this would be true in the prevailing number of practical cases, should there arise a case when this limit is insufficient, it is easy to modify this solution to accept the limit-value as an external/global parameter.

Finally, Performance:

Processing an XML document similar to the above, but having 1700 str elements takes 0.659 sec. on my 8-year old Pentium single core 3GHz CPU, 2GB RAM computer.

Explanation:

  1. This is a two-pass solution.

  2. In the first pass all nodes are copied "as-is" with the exception that a sortMe attribute is added to every str element. This attribute contains the string value of the only text-node child of str -- in which any number is left-padded with spaces to a total fixed length of 40.

  3. In Pass 2 we are sorting all str elements alphabetically using a single sort key -- the sortMe attribute.

Now, to answer all the 4 original questions:

My question is:

Is XSL the best sorting option for this particular problem?
If so how can I use XSL to do Natural Sort? (url to resources?)
If yes to both questions, which library should I use for the best compatibility and speed?
If XSL is not the best choice, then which one is?

Answers:

  1. Any implementation of an optimal sort algorithm (regardless of the language) should suffice. In this regards XSLT is a good choice.

  2. The code above provides a complete and exact XSLT implementation of "natural" sort.

  3. No library is necessary -- just use the above code as is. If you need assistance how to invoke a transformation from your PL, consult the appropriate documentation.

  4. Any PL, XSLT included, with an implementation of an optimal sorting algorithm is a suitable choice.

How to create Java objects from XML tags which are referring each other?

5 votes

I have an XML which has tags corresponding to three types of Java objects which would be created from the XML. The objects are of the form:

A
- static Map<String, A>
- String name
- String aInfo1
- String aInfo2

B
- static Map<String, B>
- String name
- String bInfo1
- String bInfo2

C
- A aObject
- B bObject

Now, in my XML, I define a list of tags for A objects and B objects and then I define tags for C objects which refer to A and B objects using there name field. I have two requirements:

  1. populate static maps in A and B while reading the A and B objects from XMLs. The maps will contain a mapping of A.name to A, and B.name to B respectively.
  2. populate C objects by reading the A.name and B.name from XML tag and then using the maps defined in A and B objects.

I have read about some Java frameworks like JAXB but I am unable to come up with a way to create such type of objects from my XML. Is there a framework in Java which can do this out-of-the box or with minimum logic?

Edit:

There is another requirement: I need to define D and E objects of the form

D
- Map<A, E>

I would define E objects similar to how servlets are defined in web.xml i.e. first define the name and class for the E class and then use the name for E at some other place. Additionally, pass parameters to instantiate E objects. The tag would look like:

<E>
    <name>queryProcessor</name>
    <class>com.mydomain.QueryProcessor</class>
</E>

Now this would be used while defining content of Map in D

<D>
    <map>
        <A>name_of_some_A_object</A>
        <E name="queryProcessor">
            <param1>name_of_some_B_object</param1>
            <param2>name_of_some_B_object</param2>
        </E>
        <A>name_of_some_A_object</A>
        <E name="queryProcessor">
            <param1>name_of_some_B_object</param1>
            <param2>name_of_some_B_object</param2>
        </E>
     </map>
 </D>

Essentially the map in D will be populated by instantiating a class of base type E with the parameters passed to it and an object of A, referred by its name.

  • Specify the correct XML format with an XSD
  • Generate the JAXB classes

(You could do it also the other way around, if you are familiar with JAXB annotations and want to control the interface with Java rather than with an XSD).

Note: static Maps is most likely not what you want to use. If you explain more about what problem you want to solve we might be able to point you out some alternative ways

Edit:

Are you talking about the format of the XML? Or why I need XML at all? I need XML for the ability to make my applications configurable outside of Java.

It looks like you're re-inventing the wheel. Have a look at Spring and see if it fits your needs. If it doesn't, explain why.

Serialize an object to XElement and Deserialize it in memory

5 votes

I want to serialize an object to xml but I don't want to save it on the disk.I want to hold it in a XElement varialble(for using Linq) and then deserialize back to my object.

How I can do this?

thanks

You can use these two extension methods to serialize and deserialize between XElement and your objects.

public static XElement ToXElement<T>(this object obj)
{
    using (var memoryStream = new MemoryStream())
    {
        using (TextWriter streamWriter = new StreamWriter(memoryStream))
        {
            var xmlSerializer = new XmlSerializer(typeof(T));
            xmlSerializer.Serialize(streamWriter, obj);
            return XElement.Parse(Encoding.ASCII.GetString(memoryStream.ToArray()));
        }
    }
}

public static T FromXElement<T>(this XElement xElement)
{
    using (var memoryStream = new MemoryStream(Encoding.ASCII.GetBytes(xElement.ToString())))
    {
        var xmlSerializer = new XmlSerializer(typeof(T));
        return (T)xmlSerializer.Deserialize(memoryStream);
    }
}

USAGE

XElement element = myClass.ToXElement<MyClass>();
var newMyClass = element.FromXElement<MyClass>();

cannot read yahoo xml feed in php

5 votes

i am trying to read the yahoo rss (http://news.yahoo.com/rss/us) in php using the xml function

this is myvery simple code:

 $xml = simplexml_load_file('xml.xml');
 var_dump($xml['channel']);

but i shows NULL:

adam@cka: php test.php
NULL

is my XML broken? or there's a better function in php to read xml file?

i can see the elment exists in the XML file and i downloaded the file correctly in my computer.

SimpleXML returns an object, not an array. Try this:

<?php
 $xml = simplexml_load_file('http://news.yahoo.com/rss/us');
 var_dump($xml->channel);
?>

Join strings with XML node between in scala

5 votes

I have a list of strings and I need to join them together with <br/> tags in between. So starting from:

val list = List("line1", "line2", "line3")

I need to end up with a NodeSeq of:

line1<br/>line2<br/>line3

It's possible the list contains only one element, in which case I should end up with a NodeSeq just of Text("line1").

Is there a one-liner to do this, using one of the higher order functions on list? I've tried to play around with foldLeft but can't seem to get it to do what I want.

list.map(scala.xml.Text(_):scala.xml.NodeSeq).reduce(_ ++ <br /> ++ _)

Note that we have to widen the type to scala.xml.NodeSeq manually as Text is too restrictive for the reduce method. The more concise

list.map(scala.xml.Text).reduce(_ ++ <br /> ++ _)

won’t compile.

Using xquery FLWOR expressions to find multiple "where" restrictions

4 votes

I am trying to find employees who work on projects located in Houston but the department the project is housed in is not located in Houston. I was trying to model the expression after this example of FLWOR expressions but the query doesn't return anything and it should return results.

edit: Here is the input.

xquery
let $doc := doc("~path/company.xml")
for $e in $doc//employee,
    $d in $doc//department,
    $p in $doc//projects
where $d/locations[location!="Houston"]
and $p/project[plocations="Houston"]
return <e>{$e/fname}{$e/lname}{$e/address}</e>
/

One for clause is enough; otherwise, you'll iterate over all employees several times:

let   $doc := doc(...)
for   $e in $doc//employee
let   $p := $doc//project[@pnumber = $e/projects/worksOn/@pno]
where $p[plocation = 'Houston']
  and $doc//department[@dno = $p/@controllingDepartment]
                      [not(locations/location = 'Houston')]
return <e>{ $e/fname }{ $e/lname }{ $e/address }</e>

Using XPath count() with contains()

4 votes

I am working with the following (suboptimal) XML:

<a>
  <b>
    <c>X:1 Y:0</c>
    <c>X:1 Y:0</c>
    <c>X:2 Y:0</c>
  </b>
  <b>
    <c>X:1 Y:0</c>
    <c>X:2 Y:0</c>
  </b>
</a>

I am trying to use XPath to count the number of <c> nodes whose contents contain X:1:

count(contains(/a/b/c, 'X:1'))

However, this returns an error rather than returning the expected count of 3.

What am I doing wrong?

That isn't how you use contains(). Try

count(/a/b/c[contains(., 'X:1')])

Why are these XML tags creating an error in my PHP?

4 votes

I am trying to use XML in a PHP document. I am getting an error for the <?xml and the ?> tags. I assume PHP is trying to read the XML tags as PHP tags. Does anyone know what bug is?

<body>
     <?xml-stylesheet type="text/css" href="stylebox.css" ?> 
     <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
         <rect id="p1" x="100" y="100" width="100" height="100" />
         <rect id="p2" x="200" y="100" width="100" height="100" />
     </svg>
</body>

This is short php open tags creating problem. Change settings in you php.ini file

Put :

short_open_tag = Off

Otherwise assign this value in a variable in place of <?xml-stylesheet type="text/css" href="stylebox.css" ?> :

$XMLstr='<?xml-stylesheet type="text/css" href="stylebox.css" ?>';

echo $XMLstr;

What library to use to *write* XML file in a C++ program?

4 votes

What library to use to write XML file in a C++ program?

I've found two classes posted in CodeProject

but want to check if there is more standard option than these. I'm only concerned with writing, and not parsing XML.

I tried different libraries and finally decided for TinyXml. It's compact, fast, free (zlib license) and very easy to use.