首 页 | 新 闻 | 技术中心 | 第二书店 | 《程序员》 | 《开发高手》 | 社 区 | 黄 页 | 人 才
移 动专 题SUNIBM微 软微 创精 华Donews人 邮
我的技术中心 
我的分类 我的文档
全部文章 发表文章
专栏管理 使用说明



 RSS 订阅 
最新文档列表
Windows/.NET
.NET  (rss)    
Visual C++  (rss)    
Delphi  (rss)    
Visual Basic  (rss)    
ASP  (rss)    
JavaScript  (rss)    
Java/Linux
Java  (rss)    
Perl  (rss)    
综合
其他开发语言  (rss)    
文件格式  (rss)    
企业开发
游戏开发  (rss)    
网站制作技术  (rss)    
数据库
数据库开发  (rss)    
软件工程
其他  (rss)    

积极原创作者 
iiprogram (68)
qdzx2008 (50)
goodboy1881 (14)
wangchinaking (58)
fancyhf (1)
harrymeng (41)
yjz0065 (113)
coofucoo (105)
Drate (69)
lphpc (30)
CSDN - 文档中心 - .NET 阅读:7070   评论: 1    参与评论
标题   XML规范化(二)     选择自 dy_2000_abc 的 Blog
关键字   XML SOAP 规范化
出处  

XML规范化(二)

       上一篇文章通过一个例子介绍了如何规范化XML文件,这一篇文章主要讲述XML文件子集规范化遇到的一些问题。
       我们从一个XML文件提取其中一部分内容时,一般是将一个子节点从它的父节点分离出来,我们称这个子节点为孤儿节点,提取出来的文件称为文档子集。如果孤儿节点的名字空间上下文在其父节点中声明,文档子集原来的名字空间上下文就可能丢失。下面用一个例子说明这一点。

文件1
<?xml version="1.0"?>
<SOAP:Envelope xmlns:SOAP="http://www.w3.org/2001/12/soap-envelope">
    <SOAP:Header>
        <!--Protocol specific information, such as signature etc.-->
    </SOAP:Header>
    <SOAP:Body >
        <bs:PackageBooking
            xmlns:bs="http://www.FictitiousTourismInterface/BookingService"
            xmlns:hs="http://www.FictitiousTourismInterface/HotelService"
            xmlns:cs="http://www.FictitiousTourismInterface/CarRentalService"
            xml:lang="en"            Id='VacationTours/Packages[@id=435]/booking[(@date="2002-09-23T09:06:00Z")and(@number="786")]'
            issueDate="2002-09-23T09:06:00Z">
           <bs:booking unitCharge="50"
                       unitDescription="per night"
                       units="2"
                       currency="USD"
                       status="confirmed"   >
               <item>
                   <hs:room hotelName="White Palace"
                            type="suite"
                            bookedFrom="2002-10-12T12:00:00Z"
                            bookedTo="2002-10-14T12:00:00Z"  />
               </item>
           </bs:booking>
           <bs:booking unitCharge="60"
                       unitDescription="per night"
                       units="1"
                       currency="USD"
                       status="confirmed">
               <item>
                   <hs:room hotelName="Lake View"
                            type="suite"
                            bookedFrom="2002-10-14T12:00:00Z"
                            bookedTo="2002-10-15T12:00:00Z"    />
               </item>
           </bs:booking>
           <bs:booking unitCharge="200"
                       unitDescription="per day"
                       units="3"
                       currency="USD"
                       status="confirmed">
               <item>
                   <cs:car make="Toyota"
                           type="Hiace"
                           bookedFrom="2002-10-12T12:00:00Z"
                           bookedTo="2002-10-15T12:00:00Z"/>
               </item>
           </bs:booking>
       </bs:PackageBooking>
    </SOAP:Body>
</SOAP:Envelope>
      

       假设我们只需要规范化UnitChange=50的booking元素。第一步,我们将unitCharge="50"的booking子节点提取出来,文件2是提取出来的文档子集。在文件2中,我们不知道bs和hs前缀是什么,原因是提取的文件丢失了它们的名字空间声明。另外一点,在文件1中,bookingPackage元素的属性xml:lang被应用于所有的子节点,文件2把这个属性也丢失了。


文件2
<bs:booking unitCharge="50"
    unitDescription="per night"
    units="2"
    currency="USD"
    status="confirmed"   >
    <item>
        <hs:room hotelName="White Palace"
                 type="suite"
                 bookedFrom="2002-10-12T12:00:00Z"
                 bookedTo="2002-10-14T12:00:00Z"  />
    </item>
</bs:booking>
    

       鉴于上面的原因,XML规范化规则中定义了两条规则来处理子文档提取的问题:
1   在文档子集中被忽略的父级名字空间声明要添加到文档子集中。
2   XML名字空间的属性也要添加到文档子集中。
       应用这两条规范化规则后,提取出来的文件如文件3所示。


文件3
<bs:booking xmlns:bs="http://www.FictitiousTourismInterface/BookingService" xmlns:cs="http://www.FictitiousTourismInterface/CarRentalService" xmlns:hs="http://www.FictitiousTourismInterface/HotelService"
xmlns:SOAP="http://www.w3.org/2001/12/soap-envelope"
currency="USD" status="confirmed" unitCharge="50" unitDescription="per night" units="2" xml:lang="en">
     <item>
                 <hs:room bookedFrom="2002-10-12T12:00:00Z" bookedTo="2002-10-14T12:00:00Z" hotelName="White Palace" type="suite">
                 </hs:room>
     </item>
</bs:booking>
      

       事情总比人们想象的复杂几乎就是一个定理,这里也不例外。在一些特殊的情况下上述做法会产生一些新问题。为了详细描述这样的特殊情形,我们首先简要介绍一下“封装”的概念。

封装
        SOAP是一种基于xml的,用于在web上交换结构化和类型信息的简单的协议,它定义了在信封中包装xml数据的格式。我们再回过头来看看文件1,它将PackageBooking元素包装在SOAP:Body元素中。文件1阐述了一个简单的封装机制:传递的信息被包装在SOAP:Body元素中,整个SOAP:Body元素又被包装在SOAP:Envelope元素。
       下面我们来看一个会发生问题的情景。
       一个游客想通过旅行社提供的Web服务了解旅行的细节,于是,这个游客给旅行社发了一个xml信息,信息中包含了他计划去旅行的地点和时间,所有的信息被放到一个SOAP信封中。当然,这个xml信息由客户端的程序生成,这位游客没有必要去了解xml和soap。
       旅行社收到这个SOAP信封后,它的Web服务从信封中提取旅游地点和时间的信息,然后把这些信息重新封装,接着将这些信息发往几个不同的饭店和汽车出租公司。在这里,旅行社的Web服务需要生成一个新的SOAP信封。
       按照同样的方式,在旅行社收到饭店和汽车出租公司返回的信息后,它将这些信息重新封装再发回给旅客。
       文件4是一个饭店返回给旅行社的SOAP信息样例。


文件4
<?xml version="1.0"?>
<SOAP:Envelope xmlns:SOAP="http://www.w3.org/2001/12/soap-envelope">
    <SOAP:Header>
        <!--Protocol specific information, such as signature etc.-->
    </SOAP:Header>
    <SOAP:Body
           xmlns:bs="http://www.FictitiousTourismInterface/BookingService"
           xmlns:hs="http://www.FictitiousTourismInterface/HotelService">
           <bs:booking unitCharge="50"
                       unitDescription="per night"
                       units="2"
                       currency="USD"
                       status="confirmed"   >
               <item>
                   <hs:room hotelName="White Palace"
                            type="suite"
                            bookedFrom="2002-10-12T12:00:00Z"
                            bookedTo="2002-10-14T12:00:00Z"  />
               </item>
           </bs:booking>
    </SOAP:Body>
</SOAP:Envelope>

        旅行社可能还从其他的饭店和汽车出租公司收到SOAP信息,它需要将这些信息需要合并到一个信封中,然后返回给旅客。文件1是旅行社最后发给游客的SOAP信息包,文件1第一个booking元素与文件4中的booking元素是一样的。
        现在,我们假设饭店希望对文件4的booking元素进行签名,这样,旅行社和游客可以验证booking是否被非法篡改过。签名的第一步是提取booking元素,然后对提取的文档子集进行规范化处理,得到文件5。


文件5
<bs:booking xmlns:bs="http://www.FictitiousTourismInterface/BookingService"  xmlns:hs="http://www.FictitiousTourismInterface/HotelService"
xmlns:SOAP="http://www.w3.org/2001/12/soap-envelope"
currency="USD" status="confirmed" unitCharge="50" unitDescription="per night" units="2">
      <item>
               <hs:room bookedFrom="2002-10-12T12:00:00Z" bookedTo="2002-10-14T12:00:00Z" hotelName="White Palace" type="suite">
              </hs:room>
      </item>
</bs:booking>
      

       饭店收到文件5后,使用它来生成信息摘要。饭店进行验证通过后,如前所述,将各方面的信息合并,然后返回给顾客。这个过程如图1所示。


       如图1示,旅客收到了旅行社的SOAP信封,旅客的Web服务程序将SOAP信封打开,提取并验证信息。首先,按照前面所讲的XML规范化规则从文件1提取booking元素,提取得到的文档子集是文件3;接着,程序对文件3生成一个信息摘要并将其与收到的信息摘要进行比较验证,显然,结果将是验证失败。这时,旅客将认为信息被非法修改过了,可事实上,这些信息并没有被修改。
       这样的情景在联合Web服务中是很常见的,为了处理这些问题,W3C专门制定了另外一份规范化规则《专用XML规范化规则》,这份专门的规则只在规范化文档子集时使用。


相关文章
对该文的评论
pweb ( 2002-12-09)
我找到一个很不错的编程,网络安全论坛!http://www.yiii.net/app/club/