當 XML 遇到 XSL 及各類瀏覽器所產生的火花 !!

學習 XML 與 XSL 整合應用,已經有一段很長的日子。
之前,一直是以看看的心態在學它,所以,原理、語法及資料的呈現顯示,這只"看看"而已。沒有做太多的琢磨。

近來,工作上有所需要,且需實作以體現相關的結果來,才再次拿書作戰。這一戰才知問題多多 !!

  1. 事隔多年,各家瀏覽器的版本及功能,功能都已有大躍進。
  2. 要在瀏覽器上呈現資料,即然也不同;有的可以用拖拉帶入,有的則不可以,反需要用網頁伺服器的方式才行。
    也就是說,要用網頁方式來運行;如在 IIS 中,設定一個可瀏覽的虛擬目錄,再去瀏覽該目錄下的檔案。
  3. XSL 的 版本及指令語句的配合,也要相一致。

 

綜合上述摘要,結論如下:(2012/07/20 提記)

Google Chrome 20.0.1132.57 網頁伺服器呈現資料,XSL V1.0 不可用
Internet Explore 6.0.2900.5512 可拖拉,XSL V1.0, V2.0 均可用
Mozilla FireFox 12.0 可拖拉,XSL V2.0 均可用
   
XSL V1.0               XML <?xml-stylesheet type="text/xsl" href="配搭的XSL檔案.xsl"?>
                             XSL <xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
   
XSL V2.0               XML

<?xml-stylesheet type="text/xsl" href="配搭的XSL檔案.xsl"?>
<RootElementName
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

                             XSL

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi ="http://www.w3.org/2000/10/XMLSchema-instance">

XSL V2.0               XML
(自訂 Namespace)

<?xml-stylesheet type="text/xsl" href="配搭的XSL檔案.xsl"?>
<RootElementName
xmlns=http://My-Company.com/namespace
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://My-Company.com/namespace">

                             XSL
(自訂 Namespace)

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi ="http://www.w3.org/2000/10/XMLSchema-instance"
xmlns:my=http://My-Company.com/namespace>

My-Company.com 依實務需要加以變更。

配合 XSL 體現含中文字的 XML會有亂碼?

個人使用 Altova XMLSpy 2012 版本,配合 XSL 在體現 XML 文件時,發現中文字有部份亂碼,
不知該如何排解?
** 使用 該軟體的 XSL Transfermation (F10) 的功能。

呈現出不正常的結果

image

其運作的過程中,出現的下列幾個錯誤訊息:

image

image

為了解問題所在;改在 IIS 下,重新瀏覽該檔案,則發現到一點問題也沒有。
(密訣:直接在 IIS 中,設定一個可瀏覽的虛擬目錄,再去瀏覽該目錄下的檔案,即可。)

image

要如何取得 MS-SQL 資料表的結構訊息?

要得知資料表的結構訊息,可以用 sp_columns 'Table_Name'   這是在 Query Analyzer 中運行。

若是要在 程式中 來取得相關表結構訊息,則要配合 syscolumnssysobjects 或是 syscolumns 及object_id()。

方法一:
select  a.*  from syscolumns a
left join sysobjects b on a.id=b.id
where b.name='Table_Name'

方法二:
select * from syscolumns where id=object_id('Table_Name')

其中有些欄位意義如下:
name  : 欄位的名稱
xtype  : 用以表示欄位的資料型態,可參考文章:SQL 系統資料表 syscolumns 的 xtype 數據意義?
length : 表示該欄位的寬度

SQL 系統資料表 syscolumns 的 xtype 數據意義?

SQL 系統資料表 syscolumns 記錄得資料庫中,所有被建置的資料表最重的訊息。
諸如:欄位名稱、寛度、資料型態…等。

其中,用以表示欄位的資料型態,是被呈現在 xtype 欄位中。但該欄位是以數字值來表示。
該如何得知該數字的含義?

事實上,相關資料是存放在 systypes 資料表中。

select * from systypes
order by xtype

------------------------------------------------------------
34    image
35    text
36    uniqueidentifier
48    tinyint
52    smallint
56    int
58    smalldatetime
59    real
60    money
61    datetime
62    float
98    sql_variant
99    ntext
104    bit
106    decimal
108    numeric
122    smallmoney
127    bigint
165    varbinary
167    varchar
173    binary
175    char
189    timestamp
231    sysname
231    nvarchar
239    nchar
------------------------------------------------------------

Windows installer error, Error Code : 2869

在 Windows 7 下,安裝一 *.msi 程式,運行時卻產生錯誤:2869.

這問題要如何排除?

Google 一下,得到一文章:
http://social.msdn.microsoft.com/Forums/en-US/windowsgeneraldevelopmentissues/thread/c1326233-3f10-4d98-96a7-4a22e5eeaa2d/

提到,先建置一 vbs 檔案,以修正環境的設定值。其方法如下:
1. 建置 NoImpersonate.vbs (本文的後端會詳述內容)
2. 運行 VBS。
    cscript NoImpersonate.vbs <msi-file>
    ex: cscript NoImpersonate.vbs "Lorom ERP Develop Setup.msi"
3. 再重新執行一次 MSI。

check this link : http://msdn2.microsoft.com/en-us/library/aa368069.aspx

NoImpersonate.vbs 程式碼,條列
'------------------------------------------------
Option Explicit
'' Constant values from Windows Installer
Const msiOpenDatabaseModeTransact = 1
Const msiViewModifyInsert = 1
Const msiViewModifyUpdate = 2
Const msiViewModifyAssign = 3
Const msiViewModifyReplace = 4
Const msiViewModifyDelete = 6
Const msidbCustomActionTypeInScript = &H00000400
Const msidbCustomActionTypeNoImpersonate = &H00000800

Dim databaseFile
Dim installer : Set installer = Nothing
Dim database : Set database = Nothing
Dim sql
Dim View, Record
Dim openMode : openMode = msiOpenDatabaseModeTransact
On Error Resume Next

Call Main()

Sub Main()
   If WScript.Arguments.Length <> 1 Then
      Fail("Usage is: cscript " & WScript.ScriptName & " [msi file]")
   End If
   databaseFile = WScript.Arguments(0)
   'WScript.Echo(WScript.ScriptName & ": operating on file '" & databaseFile & "'")
   '' Instantiate Windows Installer object
   Set installer = WScript.CreateObject("WindowsInstaller.Installer") : CheckError
   '' Open the MSI database
   Set database = installer.OpenDatabase(databaseFile, openMode) : CheckError
   Proc1 : CheckError
   'Proc2 : CheckError
   If openMode = msiOpenDatabaseModeTransact Then
      database.Commit
   End If
   WScript.Quit 0
End Sub

Sub Proc1()
   '' 1. problem: CustomActions in Vista have to run with NoImpersonate
   sql = "SELECT `Action`, `Type`, `Source`, `Target` FROM `CustomAction`"
   Set View = database.OpenView(sql) : CheckError
   View.Execute : CheckError
   Do
      Set Record = View.Fetch
      If Record Is Nothing Then Exit Do
      'typeVal = Record.IntegerData(2)
      If (Record.IntegerData(2) And msidbCustomActionTypeInScript) <> 0 Then
         'WScript.Echo "Here 1, Type=" & Record.IntegerData(2)
         Record.IntegerData(2) = Record.IntegerData(2) Or msidbCustomActionTypeNoImpersonate
         'WScript.Echo "Here 2, Type=" & Record.IntegerData(2)
         View.Modify msiViewModifyReplace, Record : CheckError
      End If
   Loop
   View.Close
End Sub

Sub Proc2()
   '' 2. problem: explicit format User-Errors, otherwise they are not visible in Vista, the User just sees Error 2869
   sql = "INSERT INTO `Error` (`Error`, `Message`) VALUES (1001, 'Error [1]: [2]')"
   Set View = database.OpenView(sql) : CheckError
   WScript.Echo "Here 2"
   View.Execute : CheckError
   WScript.Echo "Here 3"
   View.Close
End Sub

Sub CheckError
   Dim message, errRec
   If Err = 0 Then Exit Sub
   message = Err.Source & " " & Hex(Err) & ": " & Err.Description
   If Not installer Is Nothing Then
      Set errRec = installer.LastErrorRecord
      If Not errRec Is Nothing Then message = message & vbLf & errRec.FormatText
   End If
   Fail message
End Sub

Sub Fail(message)
   Wscript.Echo message
   Wscript.Quit 2
End Sub
'------------------------------------------------

Code snippet 工具程式的使用範例

   1: <?php



   2: //$host = "localhost";



   3: $host = "instance19216.db.xeround.com";



   4: $port = "12784";



   5: $db    = "school";



   6: $user    = "perton";



   7: $pass    = "12345";



   8:  



   9: //$conn = mysql_pconnect("mysql:host='instance19216.db.xeround.com:12784';dbname=$db", $user, $pass);



  10: $conn = mysql_pconnect("instance19216.db.xeround.com:12784","perton","12345");



  11:   if (!$conn)



  12:     die('Could not connect: ' . mysql_error());


  13:   mysql_select_db("school");



  14:  



  15:  



  16: $sql = "SELECT * FROM student";



  17: $q     = $conn->query($sql) or die("failed!");



  18:  



  19: while($r = $q->fetch(PDO::FETCH_ASSOC)){



  20:   echo $r['name'] . "<br />";



  21: }



  22: ?>


將 saveXML() 的內容呈現在螢幕上

看下程式碼,就會明白

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ex19-2</title>
</head>
<?php
$dom = new DOMDocument('1.0', 'utf8');

// 建立根元素 <companies>
$root = $dom->createElement('companies');
$root = $dom->appendChild($root);

// ----------------------------------
// 建立新的 <company> 節點
$company = $dom->createElement("company");
$root->appendChild($company);

// 建立 <company> 節點的子節點 <name>
$name = $dom->createElement("name");
$name->nodeValue = "松崗資訊股份有限公司";
$company->insertBefore($name, $company->firstChild);
// 建立 <company> 節點的子節點 <short>
$short = $dom->createElement("short");
$short->nodeValue = "松崗圖書";
$company->appendChild($short);

// ----------------------------------
// 建立新的 <company> 節點
$company = $dom->createElement("company");
$root->appendChild($company);

// 建立 <company> 節點的子節點 <name>
$name = $dom->createElement("name");
$name->nodeValue = "樂榮工業股份有限公司";
$company->insertBefore($name, $company->firstChild);
// 建立 <company> 節點的子節點 <short>
$short = $dom->createElement("short");
$short->nodeValue = "樂榮工業";
$company->appendChild($short);

// 會讓 xml 文件以有換行、內縮效果
$dom->formatOutput = true;

// 將 xml 內容,呈現在螢幕上
echo "<xmp>" . $dom->saveXML() . "</xmp>";

// 儲存 XML 文件 publisher.xml
$dom->save('publisher.xml');
?>
</body>
</html>

程式效果,如下:

<?xml version="1.0" encoding="utf8"?>


<companies>


  <company>


    <name>松崗資訊股份有限公司</name>


    <short>松崗圖書</short>


  </company>


  <company>


    <name>樂榮工業股份有限公司</name>


    <short>樂榮工業</short>


  </company>


</companies>