(根據http://www.sybase.com/sb_content/1027266/XML_PB_DOM.pdf 翻譯整理)
本文對PBDOM技術進行相關介紹,但並不涉及XML的基礎知識,建議閱讀者對下述相關術語有一定了解:Document(文檔), DTD(文檔類型定義), schema(大綱),Element(元素), attribute(屬性), processing instruction(處理命令), entity(實體)。
本文主要包括以下內容:
1、爲什麼要使用PBDOM以及怎樣創建PBDOM
2、PBDOM主要用於那些地方
3、如何使用PBDOM編程
4、PBDOM和其他XML解析(parser)技術的比較
一、什麼是DOM
◆文檔對象模型(Document Object Model)
1、作爲一項W3C規範,XML DOM存在目的是爲不同類型的應用程序提供一個標準的編程接口,它被設計可以跨平臺、跨語言使用。
2、我們可以利用XML DOM創建XML文檔並操縱其結構,增加、修改、刪除元素。
3、程序中調用XML解析器載入XML文檔到內存中。當文檔被載入後,可以通過進入DOM檢索和操作相關信息。
4、DOM 保存了XML文檔樹,文檔(document)元素位於整棵樹的最頂層。該元素可以有一到多個子節點來保存樹的結構。
可以參閱以下網站:http://www.w3schools.com/dom/ 來了解更多的關於XML Document Object Model的內容。
二、什麼時候應該使用DOM工具
◆當你需要做下列事情的時候,你應該想到XML DOM的
1、在一個或者多個XML文檔之間移動元素
2、創建新的元素並且在XML文檔的任意位置插入
3、操作元素並重新插入其到XML文檔其他位置
4、導入內嵌數據結構
& . pb9中,數據窗口現在可以通過XML導出內嵌數據結構(nested data structures).
三、什麼是PBDOM
◆PowerBuilder 文檔結構模型(PowerBuilder Document Object Model)
1、PBDOM是通過PBNI擴展出來的,用於操作XML數據,並針對PowerScript作了優化
2、在程序中模型是通過DOM的抽象來表示XML數據。(A programming model to represent XML data –an abstraction of DOM)
3、底層是對Apache Xerces/C++的封裝。
四、PBDOM的設計目標
1、簡單易用(Be straightforward for PowerBuilder programmers)
2、可以利用PowerScript的強大語言能力(如對象、方法重載、數據等)
3、在可能的情況下,隱藏了XML底層的複雜實現(Hide the complexities of XML wherever possible)
4、原有的DOM在pb下使用不夠直觀(DOM is unintuitive to a PowerBuilder programmer)
五、使用PBDOM初步
◆PBDOM設置
1、添加pbdom90.pbd(%SYBASE%/Shared/PowerBuilder)到工程的pbl列表中
2、%SYBASE%/Shared/PowerBuilder應該在系統路徑或者應用程序的路徑中(也就是pbdom要使用此路徑下的pbdom90.dll, pbxerces90.dll、xerces_2_1_0.dll文件,同樣,當程序發佈時候也需要)
六、PBDOM類的使用
◆如圖所示,反映了PBDOM類的組成和繼承關係,可以看到,幾乎所有的PBDOM類都繼承自PBDOM_Object(除了PBDOM_Builder和PBDOM_Exception)
1、PBDOM_Document
◆構建PBDOM舉例
1.1 直接構建(XML documents can be created from scratch)
PBDOM_Document doc
PBDOM_Element rootdoc = CREATE PBDOM_Document
root = CREATE PBDOM_Element
root.SetName( "root" )
root.SetText( "this is the root" )
doc.AddContent( root )
1.2 從文件、字符串、DataStore中載入
PBDOM_Builder builder
doc = builder.BuildFromString( "<foo>bar</foo>" )
doc = builder.BuildFromFile( "c:/foo/bar.xml"
doc = builder.BuildFromDataStore( l_ds)
2、PBDOM_Element
2.1 遍歷元素
PBDOM_Element root, children[], first
// Get the root element of the document
root = doc.GetRootElement()
// Get an array of all child elements
root.GetChildElements( children )
// Get only elements with a given name
root.GetChildElements( "name", children )
// Get the first element with a given name
first = root.GetChildElement( "name" )
注意:
上例中得到的元素數組是聯動的!(The element array is live!) 即:
◆ 修改數組中的元素,同樣會作用到父文檔
◆ 返回的數組是有界的(Once the array is returned, it is now bounded)
◆ 在數組中增加新元素時,需要一個SetContent()方法調用
2.2 移動元素
// PBDOM_Document docOne,docTwo
PBDOM_Element movable
movable = CREATE PBDOM_Element
Movable.SetName( "movable" )
docOne.AddContent( movable ) // add
movable.Detach() // remove
docTwo.addContent( movable ) // add again
注意:
1、只要是從PBDOM_Object繼承的對象,都可以調用Detach()方法(如Comments、ProcessingInstructions、Elements (and their content)等等)
2、PBDOM元素對象不是永久的捆綁在它的父文檔上的(PBDOM elements aren't permanently tied to their parent document)
2.3 符合規格(Always well-formed)
PBDOM_Element構造器以及setter方法會檢查元素是否符合規格:
elem.SetName( "Spaces are illegal" )
AddContent()方法也會從以下幾個方面進行檢查:
◆ 結構---樹中沒有循環(Structure –no loops in any tree)
◆ 只有一個根節點元素(One and only one root element)
◆ 相容的命名空間(Consistent namespaces)
3、PBDOM_Attribute
3.1 操作元素屬性
◆ 元素可以有多個屬性
<table width="100%" border="0"></table>
// Get an attribute
ls_width = table.GetAttributeValue( "width" ) // or
ls_width = table.GetAttribute ( "width" ).GetText()
// Attributes can be typed
li_border = table.GetAttribute( "width" ).GetIntValue()
// Set an attribute
table.SetAttribute( "cellspacing", "0" )
// Remove an attribute
table.RemoveAttribute( "cellspacing" )
// Remove all attributes
PBDOM_Attribute empty[]
table.SetAttributes( empty ) // the PowerScript way
4、PBDOM_Text
4.1 操作元素文本內容
<description>
cool demo
</description>
// the text is directly available –returns
// "~r~ncool demo~r~n"
ls_desc= elem.GetText()
// two convenience methods
ls_desc= elem.GetTextTrim()// returns "cool demo"
ls_desc = elem.GetTextNormalize()// returns "cool demo"
// text can be changed directly
elem.SetText( "a new description" )
5、PBDOM_Object
5.1 操作有混合內容的元素
<description>
<!–comment -->
<?convert units="metric" ?>
cool demo
</description>
PBDOM_Object content[]
desc.GetContent( content )
FOR i = 1 TO UpperBound( content )
CHOOSE content[i].GetObjectClassString()
CASE "pbdom_comment"
// ...
CASE "pbdom_processinginstruction"
// ...
END CHOOSE
NEXT
6、PBDOM_ProcessingInstruction
6.1 使用處理命令(Processing instructions)
<? xml-stylesheet type="text/xsl"href="foo.xsl" _fcksavedurl=""foo.xsl"" ?>
{------target------} {----------------data---------------}
// Get target (e.g., "xsl-stylesheet")
ls_target = pi.GetTarget()
// Get data (e.g., 'type="text/xsl"href="foo.xsl"')
ls_data = pi.GetText()
// Get individual values as attributes
String names[]
pi.GetNames( names )
FOR i = 1 TO UpperBound( names )
MessageBox( names[i], pi.GetValue( names[i] )
NEXT
7、PBDOM and 命名空間(Namespaces)
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="ffsection"
select="//SITE_SECTION
<xsl:template name="TopNav">
......
</xsl:template>
</xsl:stylesheet>
String ls_element
PBDOM_Element template
// get element name and namespace –return "xsl:template"
template = root.GetChildElement( "template" )
ls_element= template.GetNamespacePrefix() +":"+ template.Getname()
// get element by name and namespace
template = root.GetChildElement( "template", "xsl", "http://www.w3.org/1999/XSL/Transform")
七、PBDOM vs. the Competition
◆Apache Xerces/COM
Xerces 是現在PBDOM底層使用的XML解析器,但對PowerBuiler用戶來說使用不直觀。(Xerces is the [current] underlying XML parser for PBDOM, but is less intuitive)
◆MSXML
.無法在UNIX等操作系統上使用(No deployment to UNIX possible)
.同樣對PowerBuiler用戶來說使用不夠直觀(Less Intuitive)
.COM collections vs. PB arrays (pb用戶當然會優先選擇使用數組來處理數據)
◆Others
Expat–a C DLL (使用時需要聲明外部函數…使用不夠廣泛)