Wikis

XSharpCodeSamples

A few samples of the power of X# and XML-oriented programming.

Relational Databases

Retrieve all RSS Feeds from NY Times and save those entries containing the word oil in a MySQL database titled oil_news:

<xsp:append-child target="document('xdbc:mysql://192.168.1.27:3306/maindb')/oil_news">
  <xsp:for-each
    select="(document('http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml')/text() >> /library/xml/pi('import'))/channel/item[contains(title,'oil')]">
    <row>
      <title><xsp:text value="{title}"/></title>
      <description><xsp:text value="{description}"/></description>
      <link><xsp:text value="{link}"/></link>
    </row>
  </xsp:for-each>
</xsp:append-child>

Update an Oracle table containing customers with a map image obtained from Yahoo Maps:

<xsp:for-each select="document('xdbc:oracle:thin:scott@tiger//myhost:1521/orcl')/customers/*]">
  <!-- Update 'image_blob' column of each record with a map image -->
  <xsp:append-child target=".">
    <image_blob>
      <xsp:with>
        <xsp:context>
          <appid>myapp</appid>
          <street><xsp:text value="{STREET}"/></street>
          <city><xsp:text value="{CITY}"/></city>
          <state><xsp:text value="{STATE}"/></state>
          <zip><xsp:text value="{ZIP}"/></zip>
        </xsp:context>
        <xsp:do>
          <!-- Contact Yahoo Maps Web Service and obtain map URL-->
          <xsp:variable name="map-url" type="string"
            select="* >> document('rest:[http://local.yahooapis.com/MapsService/V1/mapImage?messagetype=x-www-form&httpmethod=get')/text()"/>]

          <!-- Download image and return a binary text node -->
          <?xpath document($map-url)/text() ?>
        </xsp:do>
      </xsp:with>
    </image_blob>
  </xsp:append-child>

  <!-- Update database -->
  <xsp:update-node select="."/>
</xsp:for-each>

E-mail

A fully working e-mail auto-responder using only two statements. Automatically sends a message to the senders of all unseen messages in your Inbox.

<xsp:for-each select="document('imaps://imap.gmail.com?user=jkirk@gmail.com&pass=secret')/folder[@name='INBOX']/mail[@seen = 'false']">
  <xsp:append-child target="document('smtp://smtp.gmail.com')">
    <mail subject="{concat('RE: ', @subject)}" from="jkirk@gmail.com" to="{addresses/from/@address}">
      Hi <xsp:text value="{addresses/from/@name}"/>,

      I've received your message titled '<xsp:text value="{@subject}"/>' and
      I will reply to it shortly.

      --James
    </mail>
  </xsp:append-child>
</xsp:for-each>

Send an e-mail including an Excel attachment using also two statements:

<xsp:append-child target="document('smtp://smtp.gmail.com')">
  <mail subject="Report" from="jdoe@gmail.com" to="recipient@xsharp.org">
    <contents>
      <body>Contents go here</body>
      <file name="report.xls">
        <xsp:with>
          <xsp:context>
            <workbook>
              <sheet name="My Report">
                <row>
                  <cell>Name</cell>
                  <cell>Earnings</cell>
                  <cell>Quarter</cell>
                </row>
                <row>
                  <cell>John Doe</cell>
                  <cell>900873.44</cell>
                  <cell>Q1</cell>
                </row>
              </sheet>
            </workbook>
          </xsp:context>
          <xsp:execute select="/library/excel/pi('export')"/>
        </xsp:with>
      </file>
    </contents>
  </mail>
</xsp:append-child>

Migrate your Microsoft Exchange folders and messages to Gmail using one statement:

<xsp:append-child target="document('imaps://imap.gmail.com?user=jkirk@gmail.com&pass=secret')"
          select="document('imap://exchange.microsoft.com?user=jkirk&pass=secret')/*"/>

Files

Create a ZIP file containing all documents under the public Windows shared folder.

<xsp:append-child target="document('file:///home/jkirk')">
  <file name="documents.zip">
    <?xpath document('document('smb://administrator:foobar@192.168.1.77/public')')//file[ends-with(@name,'.doc')] >> /library/compress/pi('zip') ?>
  </file>
</xsp:append-child>

Upload all files under /home/jkirk/documents to an FTP server using a separate thread per file:

<xsp:append-child target="/threads">
  <xsp:for-each select="document('file:///home/jkirk/documents')//file">
    <xsp:variable name="file" type="node" select="."/>
    <xsp:pi>
      <xsp:append-child target="document('ftp://ftp.domain.com?user=jj&pass=12345')/directory[@name='upload']" select="$file"/>
    </xsp:pi>
  </xsp:for-each>
</xsp:append-child>

Consuming Web Services

The following Web application expects the query parameter and performs a search using the Yahoo search Web service, results are returned in an Excel file:

<xsp:pi xmlns:xsp="[http://www.xsharp.org/2008/xxml">]
  <xsp:set-attribute target="http-response" name="content-type">application/vnd.ms-excel</xsp:set-attribute>
  <xsp:set-attribute target="http-response/headers" name="Content-Disposition" select="'attachment; filename=yahoo_search.xls'"/>
  <xsp:with>
    <xsp:context>
      <xsp:with>
        <xsp:context>
          <appid>xsharp</appid>
          <query><xsp:value-of select="http-request/parameters/query"/></query>
        </xsp:context>
        <xsp:execute select="document('rest:[http://search.yahooapis.com/WebSearchService/V1/webSearch?messagetype=x-www-form&httpmethod=get')"/>]
      </xsp:with>
    </xsp:context>
    <xsp:do>
      <xsp:with>
        <xsp:context>
          <workbook>
            <sheet name="Search Results">
              <row><cell>URL</cell><cell>Title</cell><cell>Summary</cell></row>
              <xsp:for-each select="ResultSet/Result">
                <row><cell><?xpath Url/text()?></cell>
                  <cell><?xpath Title/text()?></cell>
                  <cell><?xpath Summary/text()?></cell></row>
              </xsp:for-each>
            </sheet>
          </workbook>
        </xsp:context>
        <xsp:execute select="/library/excel/pi('export')"/>
      </xsp:with>
    </xsp:do>
  </xsp:with>
</xsp:pi>

The following Web application expects the zip parameter and returns the weather and city name using a SOAP Web service:

<xsp:pi xmlns:xsp="[http://www.xsharp.org/2008/xxml">]
  <html>
    <xsp:with>
      <xsp:context>
        <xsp:with>
          <xsp:context>
            <ZIP><xsp:text value="{http-request/parameters/zip}"/></ZIP>
          </xsp:context>
          <xsp:execute select="document('soap:[http://ws.cdyne.com/WeatherWS/Weather.asmx?operation=GetCityWeatherByZIP&action=http://ws.cdyne.com/WeatherWS/GetCityWeatherByZIP&namespace=http://ws.cdyne.com/WeatherWS/')"/>]
        </xsp:with>
      </xsp:context>
      <xsp:do>
        <h1>Temparature in <xsp:text value="{*/*/City}"/> is <xsp:text value="{*/*/Temperature}"/>F.</h1>
      </xsp:do>
    </xsp:with>
  </html>
</xsp:pi>

Creating Web Services

Web services are created using the xws file extension. The following example demonstrates a "Hello World" Web service in one line:

<xsp:processing-instruction name="helloWorld">Hello World, <xsp:text value="{*/name}"/>!</xsp:processing-instruction>

A Calculator Web service that executes the requested operation from a function library:

<!-- Define 'calculatorService' operation -->
<xsp:processing-instruction name="calculatorService">
  <!-- Obtain web service parameters -->
  <xsp:variable name="request" type="node" select="*"/>

  <xsp:with>
    <xsp:context>
      <!-- Registered operations -->
      <xsp:processing-instruction name="+">
        <xsp:text value="{node()[1] + node()[2]}"/>
      </xsp:processing-instruction>
      <xsp:processing-instruction name="-">
        <xsp:text value="{node()[1] - node()[2]}"/>
      </xsp:processing-instruction>
      <xsp:processing-instruction name="/">
        <xsp:text value="{node()[1] div node()[2]}"/>
      </xsp:processing-instruction>
      <xsp:processing-instruction name="*">
        <xsp:text value="{node()[1] * node()[2]}"/>
      </xsp:processing-instruction>
    </xsp:context>
    <xsp:execute select="$request/left | $request/right >> processing-instruction()[name() = $request/operation]"/>
  </xsp:with>
</xsp:processing-instruction>

Functional Programming with X#

For those who love functional programming, here we demonstrate how to create a map function:

<!-- MAP function -->
<xsp:variable name="map" type="node">
  <xsp:processing-instruction name="map">
    <xsp:variable name="function" type="node" select="processing-instruction()"/>
    <xsp:processing-instruction name="result">
      <xsp:for-each select="node()">
        <?xpath . >> $function ?>
      </xsp:for-each>
    </xsp:processing-instruction>
  </xsp:processing-instruction>
</xsp:variable>

<!-- SQUARE function -->
<xsp:variable name="square" type="node">
  <xsp:processing-instruction>
    <xsp:text value="{node() * node()}"/>
  </xsp:processing-instruction>
</xsp:variable>

<!-- Returns '1', '4', '9', '16', '25' -->
<?xpath 1 .. 5 >> ($square >> $map) ?>

Or, we could compose functions as follows:

<!-- COMPOSE function -->
<xsp:variable name="compose" type="node">
  <xsp:processing-instruction name="compose">
    <xsp:variable name="functions" type="nodelist" select="processing-instruction()"/>
    <xsp:processing-instruction name="result">
      <xsp:variable name="result" type="nodelist" select="node()"/>
      <xsp:for-each select="$functions">
        <xsp:set-variable name="result" select="$result >> ."/>
      </xsp:for-each>
      <?xpath $result ?>
    </xsp:processing-instruction>
  </xsp:processing-instruction>
</xsp:variable>

<!-- Create a function to Tokenize a string by commas -->
<xsp:variable name="tokenizer" type="node">
  <xsp:processing-instruction name="tokenizer">
    <?xpath tokenize(node(),',') ?>
  </xsp:processing-instruction>
</xsp:variable>

<!-- Use compose to create a new function that
   tokenizes by commas and calculates squares -->
<xsp:variable name="token-sqr" type="node" select="$tokenizer | ($square >> $map) >> $compose"/>

<!-- Returns '1', '9', '25', '49' -->
<?xpath new-text('1,3,5,7') >> $token-sqr ?>
0 Attachments 0 Attachments
2114 Views

Average (0 Votes)