<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-72  評論-63  文章-0  trackbacks-0

    我們知道校驗XML文件的方式有XSD?和XDR兩種方式,這兩種方式是利用XML?Schema來實現的,現在我們介紹另外的一種校驗:DTD。?DTD(Document?type?definition)?校驗是使用W3C中有效性約束來實現的。DTD使用一種正式的文法來描述相適應的XML文檔的結構和語法。完成一個DTD校驗,是利用XmlValidatingReader類。XmlValidatingReader類將DTD定義在DOCTYPE中。這個DOCTYPE定義的可以包括在線的DTD或是指向一個DTD文件。

    在什么情況下使用DTD校驗呢?使用DTD校驗,可以使一個用戶組中獨立的不同的用戶使用共同的DTD來交換數據。比如,你可以使用共同的DTD校驗你所接受到的XML數據是不是有效,你也可以用DTD來校驗你自己的數據。

    下面我們用一個例子來說明DTD是如何使用的。

    首先寫一個HeadCount.dtd:

    <!ELEMENT?HeadCount?(Name)*>//ELEMENT說明元素是HeadCount

    <!ELEMENT?Name?(Name)*>?//ELEMENT說明元素是Name


    <!ATTLIST?Name?First?CDATA?#REQUIRED>//ATTLIST說明元素Name后面是屬性First

    <!ATTLIST?Name?Last?CDATA?#REQUIRED>//ATTLIST說明元素Name后面還有一個是屬性Last


    <!ATTLIST?Name?Relation?(self?|?spouse?|?child)?"self">

    <!ENTITY?MyFirst?"Jeff">

    <!ENTITY?MyLast?"Smith">


    具體的DTD規范可以參考W3C規范。

    還有一個待校驗的XML文件HeadCount.xml:

    <!DOCTYPE?HeadCount?SYSTEM?"HeadCount.dtd">

    <HeadCount>

    <Name?First="Waldo"?Last="Pepper">

    <Name?First="Salt"?Last="Pepper"?Relation="spouse"/>

    <Name?First="Red"?Last="Pepper"?Relation="child"/>

    </Name>

    <Name?First="&MyFirst;"?Last="&MyLast;">

    <Name?First="Sharon"?Last="&MyLast;"?Relation="spouse"/>

    <Name?First="Morgan"?Last="&MyLast;"?Relation="child"/>

    <Name?First="Shelby"?Last="&MyLast;"?Relation="child"/>

    </Name>

    </HeadCount>


    現在我們寫一個cs文件來實現校驗:

    testDtd.cs

    using?System;

    using?System.IO;

    using?System.Xml;

    using?System.Xml.Schema;


    class?testDtd

    {

    public?static?void?Main()

    {

    XmlTextReader?tr?=?new?XmlTextReader("HeadCount.xml");

    XmlValidatingReader?vr?=?new?XmlValidatingReader(tr);


    vr.ValidationType?=?ValidationType.DTD;

    vr.ValidationEventHandler?+=?new?ValidationEventHandler?(ValidationHandler);


    while(vr.Read());

    Console.WriteLine("Validation?finished");

    }


    public?static?void?ValidationHandler(object?sender,?ValidationEventArgs?args)

    {

    Console.WriteLine("***Validation?error");

    Console.WriteLine("\tSeverity:{0}",?args.Severity);

    Console.WriteLine("\tMessage?:{0}",?args.Message);

    }

    }


    運行這個程序,可以發現校驗正確。

    但如果我們把它改下呢?

    我們將HeadCount.dtd改成:

    <!ELEMENT?HeadCount1?(Name)*>

    <!ELEMENT?Name?(Name)*>

    <!ATTLIST?Name?First?CDATA?#REQUIRED>

    <!ATTLIST?Name?Last?CDATA?#REQUIRED>

    <!ATTLIST?Name?Relation?(self?|?spouse?|?child)?"self">

    <!ENTITY?MyFirst?"Jeff">

    <!ENTITY?MyLast?"Smith">


    既將第一個元素改成HeadCount1,再運行這個程序,結果如下:


    ***Validation?error

    Severity:Error

    Message?:The?'HeadCount'?element?is?not?declared.?An?error?occurred?at

    file:///F:/writer/validReader/testDtd/HeadCount.xml,?(2,?2).

    Validation?finished


    可以發現HeadCount.xml文件中第一個元素不是所期待的HeadCount1,所以報錯。


    恢復HeadCount.dtd文件,將HeadCount.xml改一下:

    <!DOCTYPE?HeadCount?SYSTEM?"HeadCount.dtd">

    <HeadCount>

    <Name?First1="Waldo"?Last1="Pepper">

    <Name?First="Salt"?Last="Pepper"?Relation="spouse"/>

    <Name?First="Red"?Last="Pepper"?Relation="child"/>

    </Name>

    <Name?First1="&MyFirst;"?Last1="&MyLast;">

    <Name?First="Sharon"?Last="&MyLast;"?Relation="spouse"/>

    <Name?First="Morgan"?Last="&MyLast;"?Relation="child"/>

    <Name?First="Shelby"?Last="&MyLast;"?Relation="child"/>

    </Name>

    </HeadCount>


    既將First改成First1,Last改成Last1,再運行這個程序,結果如下:

    ***Validation?error

    Severity:Error

    Message?:The?'HeadCount'?element?is?not?declared.?An?error?occurred?at

    file:///F:/writer/validReader/testDtd/HeadCount.xml,?(2,?2).

    Validation?finished


    F:\writer\validReader\testDtd>testDtd

    ***Validation?error

    Severity:Error

    Message?:The?'First1'?attribute?is?not?declared.?An?error?occurred?at?f

    ile:///F:/writer/validReader/testDtd/HeadCount.xml,?(3,?9).

    ***Validation?error

    Severity:Error

    Message?:The?'Last1'?attribute?is?not?declared.?An?error?occurred?at?fi

    le:///F:/writer/validReader/testDtd/HeadCount.xml,?(3,?24).

    ***Validation?error

    Severity:Error

    Message?:The?required?attribute?'Last'?is?missing.?An?error?occurred?at

    file:///F:/writer/validReader/testDtd/HeadCount.xml,?(3,?4).

    ***Validation?error

    Severity:Error

    Message?:The?'First1'?attribute?is?not?declared.?An?error?occurred?at?f

    ile:///F:/writer/validReader/testDtd/HeadCount.xml,?(7,?9).

    ***Validation?error

    Severity:Error

    Message?:The?'Last1'?attribute?is?not?declared.?An?error?occurred?at?fi

    le:///F:/writer/validReader/testDtd/HeadCount.xml,?(7,?28).

    ***Validation?error

    Severity:Error

    Message?:The?required?attribute?'Last'?is?missing.?An?error?occurred?at

    file:///F:/writer/validReader/testDtd/HeadCount.xml,?(7,?4).

    Validation?finished

    通過報出來的錯誤信息,我們可以得知,First1和Last1屬性在DTD文件中沒有定義,所以出錯。

    通過以上的測試,可以得知DTD校驗的一些簡單的規律,它同Xml?Schema校驗相輔相成,共同構成了XML?校驗,保證XML數據的正確性,是XML成為數據承載和傳輸的有效而可靠的載體。


    XML?問題?#9??SQL?查詢中的?DTD?和?XML?文檔

    本專欄討論了可以不依賴?RDBMS?生成可移植?XML?結果集的公眾域?sql2dtd?和?sql2xml?實用程序。從關系數據庫中抽取數據的?SQL?查詢可以提供非常實用且特殊的文檔類型信息,用于以?XML?表示查詢結果。
    前一“XML?話題”專欄討論了各種數據模型的一些基本理論和它們的優勢。得出的一個結論就是?RDBMS?已被普遍接受(有充分的理由),并且在這種環境中,最好將?XML?看作是在各種?DBMS?之間傳送數據的一種方法,而不是替代?DBMS?的事物。雖然?XPath?和?XSLT?可用于某些特定的“數據查詢”,但它們的應用遠不及?RDBMS?和(尤其是)SQL?的應用廣泛和普遍。不過,由于篇幅限制,我將在以后的專欄中討論?XPath?和?XSLT?的具體性能(和限制)。

    一些近期的?RDBMS(至少包括?DB2、Oracle,可能還有其它一些?RDBMS)都附帶了用于導出?XML?的內置(或者至少可選的)工具。不過,在本專欄中討論的工具都具有普遍性;特別是,由這些工具生成的?DTD?對于對不同?RDBMS?執行的相同查詢都是完全相同的。我希望這對實現數據透明性的目標會有所幫助。

    過于簡化
    對于將關系數據庫數據轉換成?XML,您能想像到的最明顯的方式通常也不是什么好的想法。即,它簡單到?--?無論從概念上還是從實踐上?--?將?RDBMS?的所有內容逐個表地轉儲到相應的?XML?文檔中。例如,LIBRARY?數據庫(繼續上一專欄中那個簡單示例)有一個稱作?BOOKPRICE?的表,其內容如下:

    SELECT?*?FROM?BOOKPRICE;
    +------------+-------+
    |?ISBN?|?Price?|
    +------------+-------+
    |?2994927282?|?34.99?|
    |?3920202049?|?47.50?|
    +------------+-------+

    ?

    我可以直接將它轉換成如下文檔?BOOKPRICE.xml:

    清單?1.?BOOKPRICE.xml?文檔

    <?xml?version="1.0"?>
    <SQL>
    ?<row>
    ?<ISBN>2994927282</ISBN>
    ?<Price>34.99</Price>
    ?</row>
    ?<row>
    ?<ISBN>3920202049</ISBN>
    ?<Price>47.50</Price>
    ?</row>
    </SQL>


    ?

    為數據庫中的每個表創建了類似的?XML?文檔后,您就擁有了整個數據庫的快照。

    適當簡化
    上面勾畫的方法有兩個基本問題。第一個問題是?XML?轉儲的效率非常低。您已經知道,XML?是一種非常冗長的格式,大型數據庫的?XML?轉儲會生成更大的?XML?文檔集合。而且,一些主要?DBMS?已經提供了簡潔而有效的文本文件或壓縮記錄樣式的轉儲。上面所勾畫的?XML?對這些簡單格式不但沒有提供任何額外功能,反而顯著地增加了傳送文件的大小。

    第二個問題比第一個更有趣。在某種意義上,“DASD?很廉價”,帶寬也變得越來越廉價("DASD"?是?IBM?對“硬盤”的舊稱;這個措詞在設計上很陳腐)。因此單單效率不一定就是最重要的因素。更為重要的是,您幾乎不會想要將數據庫的全部內容與伙伴/部門/用戶等進行交流。有時候,一些內容是專用的;而幾乎任何時候,大多數內容與特定用戶并沒有任何關系。

    將有用的?SQL?查詢結果轉儲到?XML?中比將原始表轉儲到?XML?更有意義。而為了將?XML?事務或饋送所需的確切語法分析和處理的預期規律化,將?DTD?與這些有用的查詢進行關聯仍然會比較好。這兩種有趣的操作恰好是公眾域?Python?實用程序?sql2dtd?和?sql2xml?能夠實現的。

    假設?A?和?B?各自有其自身的內部數據存儲器策略(例如,在不同的?RDBMS?中)。各自維護所有種類的相關信息,這些信息與?A?和?B?之間的交互沒有關系,但它們又都具有一些希望共享的信息。假設,遵循這樣的路線,A?需要與?B?循環地就特定種類的數據集進行通信。A?和?B?可以做的一件事是同意?A?將定期向?B?發送一組?XML?文檔,每個文檔都符合事先一致認可的?DTD。一個傳輸中的特定數據將隨時間而有所不同,但有效性規則已事先指定。只要?A?和?B?知道它們之間的協議,就可以執行它們的編程。

    生成?DTD
    開發?A?和?B?之間的這種通信的一個方法是開發與?A?和?B?特定需要相匹配的?DTD(或模式)。然后,A?需要開發定制代碼來將數據從?A?的當前?RDBMS?導出到符合一致的?DTD?中;B?需要開發定制代碼來導入相同的數據(到結構不同的數據庫中)。最后,通信通道被打開。

    不過通常存在一種更快速的方法?--?往往利用現有導出/導入過程的一種方法。“標準查詢語言?(SQL)”是一種能夠確切表達?RDBMS?數據庫中您所感興趣的數據的極其簡潔的方法。嘗試將例如?XPath?或?XSLT?這樣的?XML?原始技術合并到關系模型上可能不太自然,盡管它們必定可以在?XML?的基本分層模型中表達查詢功能。

    許多組織已經開發出為實現已知任務的、經過了徹底測試的幾組?SQL?語句。事實上,RDBMS?往往提供了用于優化已存儲查詢的方法。雖然肯定有一些為數據交換而設計的豐富的?DTD?比較有意義的情況,但在許多或者大多數情況下,在?SQL?查詢中隱式地使用結構信息作為?SQL?數據傳輸的(自動)基礎是種很好的解決方案。

    雖然?SQL?查詢可以以復雜的方法來組合表數據,但所有?SQL?查詢的結果都是相當簡單的“行與列”的排列。在查詢輸出中,列的數量是固定的,每行填入了每個固定列的值。(即,除了數量上沒有改變以外,無論是值的類型還是列名在?SQL?結果中均無改變?--?即使它們可能在?XML?文檔中有所改變)。XML?表示元素復雜嵌套模式的潛力在表示?SQL?結果中并沒有得到深層的體現。雖然如此,SQL?查詢的一些重要方面可以而且也應該在簡單的行/列位置以外以?XML?DTD?表示。

    要表示?SQL?查詢中的哪些內容?
    我認為在?A?和?B?之間預期的數據交換中,應該區分出兩方面。一方面,是?A?數據的內部組織?--?例如,其標準化和取消標準化優化。B?沒有,也不需要考慮?A?的內在方面。另一方面,存在描述實際發送內容的元數據。當然,區分這些方面不一定很容易。

    在編寫?sql2dtd(和幫助規劃?Scott?Hathaway?的?sql2xml)時,我做了一些決定,確定了哪些屬于數據傳輸的部分,哪些位于發送方設置的內部(不需要以?DTD?表示)。清單?2?所顯示的樣本?XML(帶有作為內部集的?DTD)輸出有助于說明這些決定(該輸出完全從作為屬性包含的?SQL?查詢生成;當然,是在對合適的數據庫運行時):

    清單?2.?帶有作為內部集的?DTD?的樣本?XML?輸出

    <?xml?version="1.0"?>
    <!DOCTYPE?SQL?[
    <!ELEMENT?SQL?(row)*>
    <!ATTLIST?SQL
    ?GROUP_BY?NMTOKEN?#FIXED?"AuthID"
    ?query?CDATA?#FIXED?"SELECT?AuthID?AS?SSN,COUNT(GroupID)
    ?FROM?AUTHGROUP?GROUP?BY?AuthID
    ?ORDER?BY?AuthID"
    >
    <!ELEMENT?row?(SSN,?column2)>
    <!ATTLIST?row?num?ID?#IMPLIED>
    <!ELEMENT?SSN?(#PCDATA)>
    <!ELEMENT?column2?(#PCDATA)>
    <!ATTLIST?column2?CALC?CDATA?#FIXED?"COUNT(GroupID)">
    ]>

    <SQL>
    ?<row?num="1">
    ?<SSN>111-22-3333</SSN>
    ?<column2>1</column2>
    ?</row>
    ?<row?num="2">
    ?<SSN>333-22-4444</SSN>
    ?<column2>2</column2>
    ?</row>
    ?<row?num="3">
    ?<SSN>666-44-5555</SSN>
    ?<column2>1</column2>
    ?</row>
    </SQL>


    ?

    這個簡單的?XML?文檔實際上可以包含比人們最初時所注意到的更多的元數據。當然,通過將?SQL?本身作為根節點的一個屬性包含在內,人們可以重新構造?SQL?中固有的任何事物。但這樣做需要對?SQL?重新進行語法分析,sql2dtd?已在文檔中表示過它,因此通常這沒有必要。

    CALC?屬性的規范包含這樣一個事實,即?XML?包含了計算過的元素。因為計算過的表達式可能很長,并且可能包含對于?XML?標記來說非法的字符,所以計算過的列僅由它們的位置命名。不過,加入元素內容的特定計算是作為標記的一個屬性包含在內的。為了避免在?XML?主體中重復屬性,它在?DTD?中指定為?#FIXED。

    如果使用計算過的列,計算往往反映使用?"GROUP?BY"?修飾符對列所進行的分組。所有這樣的分組都在根元素的?GROUP_BY?屬性中列出。

    而且,如果使用了?"ORDER?BY"?子句,每個?<row>?標記就會帶有指定輸出數據序列的?num?屬性。不過,如果結果集是無序的,則不使用?num?屬性。

    讓我們考慮一下在?DTD?中有什么東西沒有表示,就會發現它實際上確實屬于?A?的內部數據表示,而不屬于發送的消息。

    除了嵌入的原始?SQL?查詢以外,沒有保留用于查詢數據的一個或多個表的表示("FROM"?子句)。特殊的表組織只不過不是?B?需要感興趣的一些事物。事實上,A?可以在有適當傳輸協議之后徹底地修改其數據庫設計;但只要通過一些手段抽取相同的字段(列),B?就不需要擔心這一點。尤其是,因為?"AS"?子句覆蓋了實際的表的列名,所以有可能繼續發送在?A?數據庫中不再擁有任何直接文字意義的?XML?元素。

    在?sql2dtd?設計中最重要的一點是忽略了?"WHERE"?和?"HAVING"?子句(以及?JOIN、DISTINCT?和?ALL?修飾符)。和表名一樣,將數據從?A?的那些表中取出所必需的特定聯接和過濾器不是?B?應該擔心的問題。如果?A?碰巧需要將一些表聯接在一起以獲得一些數據,那只是?A?的一個標準化策略。B?可以使用也可以不使用任何類似的策略(對于不同的數據子集),兩種方法都不用擔心?A?的操作。出于相關但稍微不同的理由忽略過濾器(主要使用?"WHERE"?子句或?"DISTINCT"?修飾符)。不管出于何種商業原因,如果?A?只需要告之?B?那些其?whatzit?大于?25?的?woozles,從?B?的角度來說,它只是屬于?woozles?的性質。即,A?可能對?B?不關心的?woozles?的一個子類感興趣;但是?A?需要通過使用過濾器來獲得感興趣的內容(與不擁有它們,或將它們放在另一個表中相反)這一特定事實并不是?B?需要擔心的。從這一方面來說,sub-select?只是另一種過濾器。

    結束
    我還沒有介紹?sql2dtd?和?sql2xml?的任何特定用法。這里不需要做太多解釋,因為它們自己已在內部詳細說明了。一般情況下,?sql2dtd?可以從?SQL?查詢生成?DTD,但它本身并不查詢任何數據庫。sql2xml?通過?ODBC?執行查詢,并可以利用?sql2dtd?來獲得?DTD(它也可以生成?DTD?較少的?XML文檔)。

    這些工具只對?A?和?B?之間預期大約一半過程有所幫助。A?和?B?可以快速地使用這些工具達到?DTD,A?可以同樣快速地生成符合這些?DTD?的輸出?XML?文檔。但?B?最終仍需要執行語法分析、存儲和處理這些接收到的文檔所涉及的所有工作。以后的專欄將更詳細地討論?B?的任務。


    簡單的DTD例子描述和分析


     下面舉一個帶有內部DTD的XML文檔的例子:?

      <?xml?version="1.0"?encoding="GB2312"??>?
      <!DOCTYPE?家庭?[?
       <!ELEMENT?家庭?(人+,家電*)>?
       <!ELEMENT人?EMPTY>?
       <!ELEMENT?家電?EMPTY>?
       <!ATTLIST?人?
        名字?CDATA?#REQUIRED?
        性別?(男|女)?#REQUIRED?
        年齡?CDATA?#REQUIRED?
        愛好?CDATA?#IMPLIED?
       >?
       <!ATTLIST?家電?
         名稱?CDATA?#REQUIRED?
         數量?CDATA?#REQUIRED?
         說明?CDATA?#IMPLIED?
        >?
      ]>??
      <家庭>?
      <人>?
      <名字>郭大路?
      <性別>男?
      <年齡>25?
      ?
      <人>?
      <名字>李尋歡?
      <性別>男?
      <年齡>38?
      <愛好>作個教育家和偉人?
      ?
      <家電>?
      <名稱>彩電?
      <數量>3?
      ?
      ?

      這個文檔從第二行開始進行文檔類型聲明,包含了文檔元素(家庭)的名稱。根據定義,我們發現該元素可以包含一個或者多個人(由這個+號決定的),可以包含零個或多個家電(由這個*符號決定),然后定義了人這個元素的需要的屬性,其中名字、性別和年齡是必須的,而愛好可以填有也可以不填。家電的名字和數量屬性必須有,但說明可以寫也可以不寫。?

      如果采用外部DTD的話,就需要有兩個文檔,第一個文檔就是關于DTD的文檔,第二個文檔就是遵守DTD格式的內容文檔。實際上我們可以建立無窮多個遵守該DTD格式的文檔。舉一個例子來說,我們在構造關系數據庫中的表的時候,我們需要定義好表的結構(也就是表包含的字段集合),然后我們就可以往這個表中放入記錄,記錄的個數從理論上講可以是無窮多個的。這里關于表的結構就類似于DTD文檔。記錄類似于遵守DTD格式的內容文檔。外部DTD的好處是:它可以方便高效地被多個XML文件所共享。你只要寫一個DTD文件,就可以被多個XML文件所引用。事實上,當許多組織需要統一它們的數據交換格式時,它們就是通過外部DTD來完成的。這樣做不僅簡化了輸入工作,還保證當你需要對DTD做出改動時,不用一一去改每個引用了它的XML文件,只要改一個公用的DTD文件就足夠了。不過需要注意,如果DTD的改動不是"向后兼容"的,這時原先根據該DTD編寫的那些XML文件可能就會出問題了。?

      現在我們就嘗試建立一個DTD文檔,不妨命名為Home.dtd。其代碼如下:?

      <?xml?version="1.0"?encoding="GB2312"??>?
      <!ELEMENT?家庭?(人+,家電*)>?
      <!ELEMENT人?EMPTY>?
      <!ELEMENT?家電?EMPTY>?
      <!ATTLIST?人?
        名字?CDATA?#REQUIRED?
        性別?(男|女)?#REQUIRED?
        年齡?CDATA?#REQUIRED?
        愛好?CDATA?#IMPLIED?
       >?
      <!ATTLIST?家電?
       名稱?CDATA?#REQUIRED?
       數量?CDATA?#REQUIRED?
       說明?CDATA?#IMPLIED?
      >?

      然后,我們可以建立一個遵守該DTD格式的內容文檔,不妨設為HomeInstance.xml。其代碼如下:?

      <?xml?version="1.0"?encoding="GB2312"??>?
      <!DOCTYPE?家庭?SYSTEM?"Home.dtd">?
      <家庭>?
      <人>?
      <名字>郭大路?
      <性別>男?
      <年齡>25?
      ?
      <人>?
      <名字>李尋歡?
      <性別>男?
      <年齡>38?
      <愛好>作個教育家和偉人?
      ?
      <家電>?
      <名稱>彩電?
      <數量>3?
      ?
      ?

      把這兩個文檔放到同一個目錄下,然后可以用XML瀏覽器對HomeInstance.xml進行瀏覽,結果應該和使用內部DTD的結果一樣。?

      眾所周知,在設計MIS應用程序的時候,重要的是要進行E-R圖設計,然后建立關系數據庫,建立數據庫的關鍵就是要定義好表的格式,并使它的范式盡可能的高。對應的,建立基于XML應用的關鍵就是要定義好DTD,然后所有的內容就按照DTD格式進行編寫。DTD實際上表現了一個層次的關系,你也可以把它理解成一棵樹的結構。樹中的節點實際上就是一個個元素(ELEMENT),一個元素可以包含其他的元素。比如上面的例子中家庭這個元素包含了人和家電這兩個元素。一個元素可以包含屬性(ATTLIST)也可以沒有任何屬性。比如上面的例子中,家庭這個元素就沒有任何屬性,而人和家電都有自己的屬性。?

      際上如果大家學過編譯系統的話,都知道對編程語言進行語法定義的工具:巴科斯-諾爾范式。它是用來對語言的語法進行定義的工具。實際上DTD就是起到了類似的作用。

    posted on 2006-05-24 00:45 船長 閱讀(3962) 評論(0)  編輯  收藏 所屬分類: J2EE
    主站蜘蛛池模板: 国产成人亚洲综合a∨| 最新国产成人亚洲精品影院| 亚洲AV永久无码精品一福利 | 成人久久免费网站| 国产AⅤ无码专区亚洲AV| 一级a性色生活片久久无少妇一级婬片免费放| 永久免费毛片在线播放| 国产精品亚洲片在线va| 日本一区二区三区免费高清| 亚洲色成人WWW永久在线观看| 午夜两性色视频免费网站| 亚洲AV噜噜一区二区三区 | 在线观看亚洲成人| 中国一级特黄高清免费的大片中国一级黄色片 | 久久久久免费看成人影片| 亚洲视频国产视频| 国产大片免费网站不卡美女 | 国产aⅴ无码专区亚洲av麻豆| 少妇性饥渴无码A区免费 | 国产一级a毛一级a看免费视频| 亚洲AV无码国产在丝袜线观看| 中文字幕成人免费视频| 亚洲国产成人久久综合一区| 女人张腿给男人桶视频免费版| 污视频网站免费观看| 亚洲国产精品久久久天堂| 波多野结衣免费在线| 色九月亚洲综合网| 亚洲精品无码成人AAA片| 51视频精品全部免费最新| 亚洲GV天堂无码男同在线观看| 国产L精品国产亚洲区久久| 国产成人无码区免费网站| 亚洲国产成人精品青青草原| 国产精品极品美女免费观看 | 久久久久久久国产免费看 | 亚洲国产综合专区在线电影 | 免费国产作爱视频网站| 特级毛片A级毛片100免费播放| 亚洲AV无码国产精品麻豆天美 | 91精品视频免费|