Convertir le jeu d'enregistrements ADO en XML à l'aide de XSLT

黄舟
Libérer: 2017-02-27 16:33:38
original
1347 Les gens l'ont consulté

En raison de la véritable indépendance de plate-forme du XML (Extensible Markup Language : eXtensible Markup Language), il devient progressivement le principal support de transmission de données. XML est un langage auto-descriptif et les données elles-mêmes contiennent déjà des métadonnées, c'est-à-dire des informations sur les données elles-mêmes. Par exemple : "Mencius Chapter E 1757281793923net_lover1807581793923" Il est difficile de voir ce qu'il signifie littéralement et de combien de segments de données il se compose. Cependant, si nous utilisons XML pour le décrire comme suit, nous pouvons clairement voir la signification de chaque segment de données :

<PersonData>
  <Person>
   <姓名>孟子E章</姓名>
   <身高>175</身高>
   <体重>72</体重>
   <电话>81793923</电话>
  </Person>  
  <Person>
   <姓名>net_lover</姓名>
   <身高>180</身高>
   <体重>75</体重>
   <电话>81793923</电话>
  </Person>
 </PersonData>
Copier après la connexion

À partir du morceau de XML ci-dessus, nous pouvons non seulement voir clairement ce que signifie chaque segment de données, mais également connaître l'emplacement où les données est divisé. Dans nos applications habituelles, les résultats que nous obtenons peuvent se présenter sous la forme de tableaux, de collections ou de jeux d'enregistrements. Comment les convertir en données au format XML auto-descriptives ? Du point de vue du formulaire de données, XML est un format de texte simple de chaînes pures. Les chaînes sont très simples, rapides et faciles à transférer. Les tableaux sont parfois très lents à transférer par référence et sont très difficiles à traiter, ainsi que les collections et l'enregistrement. les ensembles sont tous deux des objets, ce qui entraînera une diminution des performances de l'ordinateur pendant le traitement, et ces objets sont associés à une plate-forme spécifique, ce qui nécessite que la plate-forme dispose d'un mécanisme de traitement intégré pour gérer les opérations sur les objets. XML est déjà une norme du W3C et est indépendant de la plate-forme. La seule exigence pour nos ordinateurs est d'être capable de traiter des chaînes XML simples, c'est-à-dire qu'il peut analyser les chaînes XML et décomposer facilement les données via une interface. segments de données indépendants afin que nous puissions y accéder. Les analyseurs XML sont petits, performants et peuvent être trouvés sur toutes les plateformes. Une fois que nous avons reçu les données XML et les avons analysées dans le style de l'exemple ci-dessus, nous pouvons les convertir en différentes représentations via XSLT (eXstensible Stylesheet Language Transformations). L'utilisation du format de données XML pour la transmission de données rendra notre travail d'écriture de code d'application plus simple et plus facile, et offrira une bonne évolutivité.
Voyons ensuite comment convertir nos données. Notre exemple est écrit sous Microsoft Windows 2000, IIS5, MSXML3 et ADO2.6. Les exemples de données utilisent la base de données exemple Northwind fournie avec Microsoft SQL Server7.0. La raison pour laquelle SQL Server7 est utilisé à la place de SQL Server2000 qui prend en charge XML est due au principe d'universalité. Notre objectif est de traiter les jeux d'enregistrements obtenus à partir de différents types de sources de données, et non seulement de prendre en charge la sortie XML comme la source de données SQL Server2000. ADO est utilisé car il a différentes formes et peut gérer différents types de sources de données ; XML est utilisé car il peut être transmis et analysé rapidement. Mais la méthode de traitement dans cet exemple convient également à tout environnement doté de l'analyseur Microsoft XML, ADO2.5 ou version supérieure de Windows, IIS, SQL Server.
Par souci de simplicité, nous sélectionnons uniquement les produits dont le prix unitaire est inférieur ou égal à 20 dollars américains, l'inventaire supérieur ou égal à 20 et les noms de produits inférieurs ou égaux à 6 caractères :


<%
  Dim objRecordset
  Set objRecordset = Server.CreateObject("ADODB.Recordset")
  objRecordset.open _
      "SELECT PRoductName, UnitPrice, UnitsInStock " _
          & "FROM Products " _
          & "WHERE UnitPrice <= 20 " _
          & "AND UnitsInStock >= 20 " _
          & "AND LEN(ProductName) <= 6 " _
          & "ORDER BY ProductName", _
      "Provider=SQLOLEDB;" _
          & "Data Source=SomeSQLServer;" _
          & "Initial Catalog=Northwind;" _
          & "User ID=MyUserName;" _
          & "PassWord=MyPassword;"
  %>
Copier après la connexion

Maintenant, nous utilisons 3 méthodes pour convertir le jeu d'enregistrements que nous avons obtenu au format XML.
Tout d'abord, nous pouvons parcourir l'ensemble de l'ensemble d'enregistrements, utiliser XML DOM (Document Object Model) et créer une arborescence de nœuds XML :

<%
  Dim objXMLDOM, objRootNode, objNode
  Set objXMLDOM = Server.CreateObject("MSXML2.DOMDocument")
  
  Set objRootNode = objXMLDOM.createElement("xml")
  objXMLDOM.documentElement = objRootNode
  
  Do While NOT objRecordset.EOF
      Set objRowNode = objXMLDOM.createElement("row")  
      Set objNode = objXMLDOM.createElement("ProductName")
      objNode.text = objRecordset.Fields.Item("ProductName").Value
      objRowNode.appendChild(objNode)
  
      Set objNode = objXMLDOM.createElement("UnitPrice")
      objNode.text = objRecordset.Fields.Item("UnitPrice").Value
      objRowNode.appendChild(objNode)
  
      Set objNode = objXMLDOM.createElement("UnitsInStock")
      objNode.text = objRecordset.Fields.Item("UnitsInStock").Value
      objRowNode.appendChild(objNode)
  
      objRootNode.appendChild(objRowNode)
  
      objRecordset.MoveNext
  Loop
  
  Set objNode = Nothing
  Set objRowNode = Nothing
  Set objRootNode = Nothing
  
  Set objRecordset = Nothing
  %>
Copier après la connexion

Maintenant, nous avons un objet XML DOM. Les performances de cette méthode ne sont pas idéales lorsque le jeu d'enregistrements est volumineux, car l'objet jeu d'enregistrements ADO et l'objet XML DOM doivent être stockés simultanément dans la mémoire système.
La deuxième méthode consiste à parcourir le jeu d'enregistrements et à générer directement la chaîne XML elle-même :

 <%
  Dim strXML
  strXML = "<xml>"
  objRecordset.MoveFirst
  Do While NOT objRecordset.EOF
      strXML = strXML & "<row>"
      strXML = strXML & "<ProductName>" _
          & objRecordset.Fields.Item("ProductName").Value _
          & "</ProductName>"
      strXML = strXML & "<UnitPrice>" _
          & objRecordset.Fields.Item("UnitPrice").Value _
          & "</UnitPrice>"
      strXML = strXML & "<UnitsInStock>" _
          & objRecordset.Fields.Item("UnitsInStock").Value _
          & "</UnitsInStock>"
      strXML = strXML & "</row>"
      objRecordset.MoveNext
  Loop
  strXML = strXML & "</xml>"
  Set objRecordset = Nothing
  %>
Copier après la connexion


Cependant, le plus gros défaut des deux méthodes ci-dessus est qu'elles ne peuvent pas être réutilisées. le code. Nous Les noms des nœuds sont écrits. Si nous effectuons des requêtes sur différents champs, nous devons également modifier manuellement notre code pour répondre aux besoins des différents nœuds. Notre approche ci-dessous deviendra plus générale.
La troisième méthode : la méthode réutilisable.

  <%
  Dim strXML
  strXML = "<xml>"
  objRecordset.MoveFirst
  Do While NOT objRecordset.EOF
      strXML = strXML & "<row>"
      For Each varItem In objRecordset.Fields
          strXML = strXML _
              & "<" & varItem.name & ">" _
              & varItem.value _
              & "</" & varItem.name & ">"
      Next
      strXML = strXML & "</row>"
      objRecordset.MoveNext
  Loop
  strXML = strXML & "</xml>"
  Set objRecordset = Nothing
  %>
Copier après la connexion


Une méthode plus efficace est que nous pouvons utiliser directement la méthode de sauvegarde intégrée du jeu d'enregistrements, qui peut automatiquement convertir le contenu du jeu d'enregistrements en Format XML. Après avoir appelé la méthode save, nous pouvons immédiatement libérer l'instance de l'objet recordset en mémoire. La méthode de sauvegarde a deux paramètres : l'un est l'endroit où le XML doit être enregistré et l'autre est un indicateur indiquant le format dans lequel les données sont enregistrées. Nous pouvons enregistrer les données en tant qu'objet XML DOM (objet ADO STREAM), ou les enregistrer directement en tant qu'objet asp RESPONSE. Par souci de généralité, nous les enregistrons en tant qu'objet XML DOM et utilisons la constante adPersistXML ADO pour le deuxième paramètre. . La méthode est la suivante :

  <%
  Const adPersistXML = 1
  Dim objXMLDOM
  Set objXMLDOM = Server.CreateObject("MSXML2.DOMDocument.3.0")
  objRecordset.save objXMLDOM, adPersistXML
  Set objRecordset = Nothing
  %>
Copier après la connexion


Cette méthode est pratique et rapide, et n'est pas sujette aux erreurs. Il n'est pas nécessaire de modifier manuellement le nom du nœud pour différentes requêtes. . Cependant, le XML produit par cette méthode n'est pas assez concis. Jetez un œil au résultat qu'il produit :

.
<xml    
xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"    
xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"    
xmlns:rs="urn:schemas-microsoft-com:rowset"    
xmlns:z="#RowsetSchema">
<s:Schema id="RowsetSchema">
    <s:ElementType        
    name="row"        
    content="eltOnly"        
    rs:CommandTimeout="30">
        <s:AttributeType            
        name="ProductName"           
         rs:number="1"            
         rs:writeunknown="true">
            <s:datatype                
            dt:type="string"                
            dt:maxLength="40"                
            rs:maybenull="false"/>        
            </s:AttributeType>
        <s:AttributeType            
        name="UnitPrice"            
        rs:number="2"            
        rs:nullable="true"            
        rs:writeunknown="true">
            <s:datatype                
            dt:type="number"                
            rs:dbtype="currency"                
            dt:maxLength="8"                
            rs:precision="19"                
            rs:fixedlength="true"/>        
            </s:AttributeType>
        <s:AttributeType            
        name="UnitsInStock"            
        rs:number="3"            
        rs:nullable="true"            
        rs:writeunknown="true">
            <s:datatype                
            dt:type="i2"                
            dt:maxLength="2"                
            rs:precision="5"                
            rs:fixedlength="true"/>        
            </s:AttributeType>
        <s:extends type="rs:rowbase"/>
    </s:ElementType>
</s:Schema>
<rs:data>
    <z:row        ProductName="Chai"        UnitPrice="18"        UnitsInStock="39"/>
    <z:row        ProductName="Konbu"        UnitPrice="6"        UnitsInStock="24"/>
    <z:row        ProductName="Tofu"        UnitPrice="23.25"        UnitsInStock="35"/>
</rs:data>
</xml>
Copier après la connexion

ADO 自动产生的XML包含了schema信息,它描述这个XML里允许有什么节点和属性以及采用何种数据类型,而且数据节点也增加了名称空间。schema信 息在需要数据验证的地方或进行更复杂的处理或许很有用,但是,大多数情况下,我们使用的是瘦客户机,我们不需要schema信息。我们可以利用XSLT来 分离出我们想要的信息,去掉多余的信息。因此,我们编写下面的“ DataCleaner.xsl”:

 <?xml version="1.0"?>
  <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
      xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
      xmlns:rs="urn:schemas-microsoft-com:rowset"
      xmlns:z="#RowsetSchema">
  
  <xsl:output omit-xml-declaration="yes"/>
  <xsl:template match="/">
      <xsl:element name="xml">
          <xsl:for-each select="/xml/rs:data/z:row">
              <xsl:element name="row">
                  <xsl:for-each select="@*">
                      <xsl:element name="{name()}">
                          <xsl:value-of select="."/>
                      </xsl:element>
                  </xsl:for-each>
              </xsl:element>
          </xsl:for-each>
      </xsl:element>
  </xsl:template>
  
  </xsl:stylesheet>
Copier après la connexion


这个XSLT具有可重用的特性,对于不同的查询结果都适用,下面就是如何使用这个XSLT的例子:

  <%
  Dim strCleanXML, objXMLDOM_XSLT
  
  Set objXMLDOM_XSLT = CreateObject("MSXML2.DOMDocument")
  objXMLDOM_XSLT.load(Server.MapPath("DataCleaner.xsl"))
  strCleanXML = objXMLDOM.transformNode(objXMLDOM_XSLT)
  
  Set objXMLDOM = Nothing
  Set objXMLDOM_XSLT = Nothing
  %>
Copier après la connexion


经过上面的处理以后,strClaenXML就是我们所想要的XML字符串了。


 <xml>
      <row>
          <ProductName>Chai</ProductName>
          <UnitPrice>18</UnitPrice>
          <UnitsInStock>39</UnitsInStock>
      </row>
      <row>
          <ProductName>Konbu</ProductName>
          <UnitPrice>6</UnitPrice>
          <UnitsInStock>24</UnitsInStock>
      </row>
  </xml>
Copier après la connexion


上面这种格式的XML字符串是我们经常见到的节点集的样式,如果您不想把字段处理成节点,而把它处理成属性节点,那么我们只需对DataCleaber.xsl稍加改动即可:

<?xml version="1.0"?>
  <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
      xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
      xmlns:rs="urn:schemas-microsoft-com:rowset"
      xmlns:z="#RowsetSchema">
  
  <xsl:output omit-xml-declaration="yes"/>
  
  <xsl:template match="/">
      <xsl:element name="xml">
          <xsl:for-each select="/xml/rs:data/z:row">
              <xsl:element name="row">
                  <xsl:for-each select="@*">
                      <xsl:attribute name="{name()}">
                          <xsl:value-of select="."/>
                      </xsl:attribute>
                  </xsl:for-each>
              </xsl:element>
          </xsl:for-each>
      </xsl:element>
  </xsl:template>
  
  </xsl:stylesheet>
Copier après la connexion


以下是采用了新样式的结果,它比用节点表示字段的长度要短的多了。传输起来速度会更快:

<xml>
   <row ProductName="Chai" UnitPrice="18" UnitsInStock="39"/>
   <row ProductName="Konbu" UnitPrice="6" UnitsInStock="24"/>
  </xml>
Copier après la connexion

  
  到此为止,我们介绍了从ADO 记录集得到XML格式数据的几种办法,也得到了最简化的字符串。但是有几个问题你仍然需要注意,有些字段值还有XML里不支持的字符,比如:"'< >&,象P&G宝洁公司的名称,Chef Anton's Gumbo Mix产品名字等,在做转换时要进行编码处理。在Microsoft ADO 2.6的SDK里有使用save方法时要注意的问题:1,save方法只对open Recordset起作用;2,不支持带有adVariant,adIDispatch,adIUnknown类型的字段的记录集的savw;3,当保存 分级的记录集( data shapes)有两个限制:不能保存参数化和含有未解决的更新的记录集。
 为了更进一步提高性能,你可以把转换工作放 到COM/COM+组件中, ASP代码只进行数据的最终表现即可。把业务层、数据层和表现层分开,ASP只需要调用数据组件,数据组件调用数据库的存储过程,把结果转换成XML,最 后只把简单的XML字符环串回到ASP程序里,ASP就可以用XSLT把XML进行转换,把结果送到浏览器。


 以上就是利用XSLT把ADO记录集转换成XML的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal