整合營銷服務(wù)商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          Qt編程進階(95):使用QXmlStreamRea

          Qt編程進階(95):使用QXmlStreamReader讀取XML

          、XML是什么?

          XML(eXtensible Markup Language,可擴展標記語言)是普遍用于數(shù)據(jù)交換和數(shù)據(jù)存儲的一種多用途文本文件格式。XML首先是由萬維網(wǎng)協(xié)會(World Wide Web Consortium,W3C)作為SGML的一個替代品來開發(fā)的。它的語法規(guī)則與HTML相似,不過XML是一種用于語言分析的語言,它并沒有要求專門的標記符,屬性或者條目。HTML的XML兼容版稱為XHTML。

          對于比較流行的SVG(可標量化矢量圖形)XML格式,QtSvg模塊提供了可用于載入并呈現(xiàn)SVG圖像的類。對于使用MathML(數(shù)學標記語言)XML格式的繪制文檔,可以使用Qt Solutions中的QtMmLWidget。

          對于一般的XML數(shù)據(jù)處理,Qt提供了QtXml模塊,這是本文的主題。

          二、XML的讀取方式

          QtXml模塊提供了三種截然不同的應(yīng)用程序編程接口用來讀取XML文件:

          • (1)QXmlStreamReader是一個用于讀取格式良好的XML文檔的快速解析器。
          • (2)DOM(文檔對象模型)把XML文檔轉(zhuǎn)換為應(yīng)用程序可以遍歷的樹形結(jié)構(gòu)。
          • (3)SAX(XML簡單應(yīng)用程序編程接口)通過虛擬函數(shù)直接向應(yīng)用程序報告“解析事件”。

          QXmlStreamReader類最快且最容易使用,它同時還提供了與其他Qt兼容的應(yīng)用程序編程接口。它很適用于編寫單通解析器。DOM的主要優(yōu)點是它能以任意順序遍歷XML文檔的樹形表示,同時可以實現(xiàn)多通解析算法。有一些應(yīng)用程序甚至使用DOM樹作為它們的基本數(shù)據(jù)結(jié)構(gòu)。SAX則因為一些歷史原因而被得以沿用至今,使用QXmlStreamReader通常會有更加簡單高效的編碼。

          使用QXmlStreamReader是在Qt中讀取XML文檔的最快且最簡單的方式。因為解析器的工作能力是逐漸遞增的,所以它尤其適用于諸如查找XML文檔中一個給定的標記符號出現(xiàn)的次數(shù)、讀取內(nèi)存容納不了的特大文件、組裝定制的數(shù)據(jù)結(jié)構(gòu)以反映XML文檔的內(nèi)容等。

          QXmlStreamReader解析器根據(jù)下圖中所列出的記號工作。每次只要調(diào)用readNext()函數(shù),下一個記號就會被讀取并變成當前的記號。當前記號的屬性取決于記號的類型,可以使用表格中列出的getter函數(shù)讀取當前記號。

          考慮如下的XML文檔:

          <doc>
          <quote>Einmal ist keinmal</quote>
          </doc>

          如果解析這個文檔,則readNext()每調(diào)用一次都將生成一個新記號,若使用getter函數(shù)還會獲得額外的信息;

          StartDocument
          StartElement (name()=="doc")
          StartElement (name()=="quote")
          Characters (text()==" Einmal ist keinmal")
          EndElement (name()=="quote")
          EndElement (name()=="doc")
          EndDocument

          每次調(diào)用readNext()后,都可以使用isStartElement(),isCharacters()及類似的函數(shù)或者僅僅用state()來測試當前記號的類型。

          三、QXmlStreamReader讀取XML實例

          下面將查看一個實例,它告訴我們?nèi)绾问褂肣XmlStreamReader解析一個專門的XML文件格式(圖1的bookindex.xml)并在QTreeWidget中顯示其內(nèi)容。所解析的是那種具有書刊索引目錄且包含索引條目和子條目的文檔格式。下圖是在QTreeWidget中顯示的書刊索引文件。

          1、QtXml庫

          在這個應(yīng)用程序中使用的QXmlStreamReader類是QtXml庫中的一部分。必須在.pro文件中加入如下一行命令:

          QT +=xml

          在代碼中添加頭文件:

          #include <QXmlStreamReader>

          2、主程序代碼

          首先查看應(yīng)用程序中XML閱讀器在上下文中是如何使用的。

          Widget::Widget(QWidget *parent)
          : QWidget(parent), ui(new Ui::Widget)
          {
            ui->setupUi(this);
            ui->treeWidget->setColumnCount(2);
            QStringList header;
            header<<"Terms"<<"Pages";
            ui->treeWidget->setHeaderLabels(header);
            XmlStreamReader reader(ui->treeWidget);
            reader.readFile("bookindex.xml");
          }

          在圖中顯示的應(yīng)用程序界面中創(chuàng)建一個QTreeWidget。之后,這個應(yīng)用程序創(chuàng)建一個XmlStreamReader,并將樹形窗口部件值傳遞給該XmlStreamReader,并要求它解析所指定的一個文件。

          3、XmlStreamReader類的定義

          然后,我們將查看閱讀器的實現(xiàn)代碼。

          class XmlStreamReader
          {
          public:
            XmlStreamReader(QTreeWidget *tree);
            bool readFile(const QString &fileName);
          private:
            void readBookindexElement();
            void readEntryElement(QTreeWidgetItem *parent);
            void readPageElement(QTreeWidgetItem *parent);
            void skipUnknownElement();
            QTreeWidget *treeWidget;
            QXmlStreamReader reader;
          };

          XmlStreamReader類提供了兩個公共函數(shù):構(gòu)造函數(shù)和readFile()函數(shù)。這個類使用QXmlStreamReader解析XML文件,并配合QTreeWidget窗口以反映其讀入的XML數(shù)據(jù)。通過使用向下遞歸的方法來實現(xiàn)這一解析過程。

          • readBookindexElement()解析一個含有0或0個以上<entry>元素的<bookindex>…</bookindex>元素。
          • readEntryElemen()解析一個含有0或0個以上<page>元素的<entry>…</entry>元素,以及嵌套任意層次的含有0或0個以上<entry>元素。
          • readPageElement()解析一個<page> …</page>元素。
          • skipUnknownElement()跳過不能識別的元素。

          4、XmlStreamReader類的實現(xiàn)

          現(xiàn)在看看XmlStreamReader類的實現(xiàn),由構(gòu)造函數(shù)開始。

          XmlStreamReader::XmlStreamReader(QTreeWidget *tree)
          {
          	treeWidget=tree;
          }

          構(gòu)造函數(shù)只是用來建立閱讀器將使用的那個QTreeWidget。所有的操作都將在readFile()函數(shù)中完成(由main()函數(shù)調(diào)用)。

          bool XmlStreamReader::readFile(const QString &fileName)
          {
            QFile file(fileName);
            if(!file.open(QFile::ReadOnly | QFile::Text)){ // (a)
              std::cerr<<"Error: Cannot read file "<<qPrintable(fileName)
              	<<": "<<qPrintable(file.errorString())<<std::endl;
              return false;
            }
            reader.setDevice(&file);
            reader.readNext(); // (b)
            while (!reader.atEnd()) {
              if(reader.isStartElement()){
                if(reader.name()=="bookindex"){ // (c)
                  readBookindexElement();
                }else{
                  reader.raiseError(QObject::tr("Not a bookindex file"));
                }
              }else{
                reader.readNext();
              }
            }
            file.close();
            if(reader.hasError()){ // (d)
              std::cerr<<"Error: Failed to parse file"
                <<qPrintable(fileName)<<": "
                <<qPrintable(reader.errorString())<<std::endl;
              return false;
            }else if(file.error()!=QFile::NoError){
              std::cerr<<"Error: Cannot read file "<<qPrintable(fileName)
              	<<": "<<qPrintable(file.errorString())<<std::endl;
              return false;
            }
            return true;
          }

          其中:

          • (a):readFile()函數(shù)首先會嘗試打開文件。如果失敗,則會輸出一條出錯信息并返回false值;如果成功,則它將被設(shè)置為QXmlStreamReader的輸人設(shè)備。
          • (b):QXmlStreamReader的readNext()函數(shù)從輸人流中讀取下一個記號。如果成功而且還沒有到達XML文件的結(jié)尾,函數(shù)將進人循環(huán)。由于索引文件的結(jié)構(gòu),我們知道在該循環(huán)內(nèi)部只有三種可能性發(fā)生:<bookindex>開始標簽正好被讀入;另一個開始標簽正好被讀入(在這種情況下,讀取的文件不是一個書刊索引);讀入的是其他種類的記號。
          • (c):如果有正確的開始標簽,就調(diào)用readBookindexElement()繼續(xù)完成處理。否則,就調(diào)用QXmlStreamReader::raiseError()并給出出錯信息。下一次(在while循環(huán)條件下)調(diào)用atEnd()時,它將返還true值。這就確保了解析過程可以在遇到錯誤時能盡快停止。通過對QFile調(diào)用error()和errorString(),就可以在稍后查詢這些出錯信息。當在書刊索引文件中檢測到有錯誤時,也會立即返回一個類似的出錯信息。其實,使用raiseError()通常會更加方便,因為它對低級的XML解析錯誤和與應(yīng)用程序相關(guān)的錯誤使用了相同的錯誤報告機制,而這些低級的XML解析錯誤會在QXmlStreamReader運行到無效的XML時就自動出現(xiàn)。
          • (d):一旦處理完成,就會關(guān)閉文件,如果存在解析器錯誤或者文件錯誤,該函數(shù)就輸出一個出錯信息并返回false值;否則,返回true值并報告解析成功。
          void XmlStreamReader::readBookindexElement()
          {
            reader.readNext();
            while(!reader.atEnd()){
              if(reader.isEndElement()){
                reader.readNext();
                break;
              }
              if(reader.isStartElement()){
                if(reader.name()=="entry"){
                  readEntryElement(treeWidget->invisibleRootItem());
                }else{
                  skipUnknownElement();
                }
              }else{
                reader.readNext();
              }
            }
          }

          readBookindexElement()的作用就是讀取文件的主體部分。它首先跳過當前的記號(此處只可能是<bookindex>開始標簽),然后遍歷讀取整個輸人文件。

          如果讀取到了關(guān)閉標簽,那么它只可能是</bookindex>標簽,否則QXmlStreamReader早就已經(jīng)報告出錯。如果是那樣的話,就跳過這個標簽并跳出循環(huán)。否則將應(yīng)該有一個頂級索引<entry>開始標簽。如果情況確實如此,調(diào)用readEntryElement()來處理條目數(shù)據(jù);不然,就調(diào)用skipUnknownElement()。使用skipUnknownElement()而不調(diào)用raiseError(),意味著如果要在將來擴展書刊索引格式以包含新的標簽的話這個閱讀器將繼續(xù)存效,因為它僅忽略了不能識別的標簽。

          readEntryElement()具有一個確認父對象條目的QTreeWidgetItem *參數(shù)。我們將QTreeWidget::invisibleRootItem()作為父對象項傳遞,以使新的項以其為根基。在readEntryElement()中,用一個不同的父對象項循環(huán)調(diào)用readEntryElement()

          void XmlStreamReader::readEntryElement(QTreeWidgetItem *parent)
          {
            QTreeWidgetItem *item=new QTreeWidgetItem(parent);
            item->setText(0,reader.attributes().value("term").toString());
            reader.readNext();
            while(!reader.atEnd()) {
              if (reader.isEndElement()) {
                reader.readNext();
                break;
              }
              if (reader.isStartElement()) {
                if (reader.name()=="entry") {
                  readEntryElement(item);
                } else if (reader.name()=="page") {
                  readPageElement(item);
                } else {
                  skipUnknownElement();
                }
              } else {
                reader.readNext();
              }
            }
          }

          每當遇到一個<entry>開始標簽時,就會調(diào)用readEntryElement()函數(shù)。我們希望為每一個索引條目創(chuàng)建一個樹形的窗口部件項,因此創(chuàng)建一個新的QTreeWidgetltem,并將其第一列的文本值設(shè)置為條目的項屬性文本。

          一旦條目被添加到樹中,就開始讀取下一個記號。如果這是一個關(guān)閉標簽,就跳過該標簽并跳出循環(huán)。如果遇到的是開始標簽,那么它可能是<entry>標簽(表示一個子條目),<page>標簽 (該條目項的頁碼數(shù)),或者是一個未知的標簽。如果開始標簽是一個子條,就遞歸調(diào)用readEntryElement()。如果該標簽是<page>標簽,就調(diào)用readPageElement()

          void XmlStreamReader::readPageElement(QTreeWidgetItem *parent)
          {
            QString page=reader.readElementText();
            if (reader.isEndElement())
            	reader.readNext();
            QString allPages=parent->text(1);
            if (! allPages.isEmpty())
            	allPages +=", ";
            allPages +=page;
            parent->setText(1, allPages);
          }

          只要讀取的是<page>標簽,就調(diào)用readPageElement()函數(shù)。被傳遞的正是符合頁碼文本所屬條目的樹項。我們從讀取<page>和</page>標簽之間的文本開始。成功讀取完以后,readElementText()函數(shù)將讓解析器停留在必須跳過的</page>標簽上。

          這些頁被存儲在樹形窗口部件項的第二列。我們首先提取那里已有的文本。如果文本不為空值,就在其后添加一個逗號,為新頁的文本做好淮備。然后,添加新的文本并相應(yīng)地更新該列的文本。

          void XmlStreamReader::skipUnknownElement()
          {
            reader.readNext();
            while (!reader.atEnd()) {
              if (reader.isEndElement()) {
                reader.readNext();
                break;
              }
              if (reader.isStartElement()) {
                skipUnknownElement();
              } else {
                reader.readNext();
              }
            }
          }

          最后,當遇到未知的標簽時,將繼續(xù)讀取,直到讀取到也將跳過的未知元素的關(guān)閉標簽為止。這意味著我們將跳過那些具有良好形式但卻無法識別的元素,并從XML文件中讀取盡可能多的可識別的數(shù)據(jù)。

          ——————————————————

          對于本文實例完整代碼有需要的朋友,可關(guān)注并在評論區(qū)留言!

          整理 | 王啟隆

          透過「歷史上的今天」,從過去看未來,從現(xiàn)在亦可以改變未來。

          今天是 2022 年 1 月 26 日,在 1997 年的今天,《紐約時報》在一篇關(guān)于新舊金山公共圖書館的文章中記錄了電子書和紙質(zhì)書之間的爭論。當時的批評者抱怨說,圖書館為計算機終端犧牲了太多的書本空間,為在線信息犧牲了太多的書籍;人們感嘆傳統(tǒng)卡片目錄的終結(jié),這標志著許多圖書館進入了信息時代。你如今還會看紙質(zhì)書嗎?回首過去,看看歷史上的 1 月 26 日還發(fā)生了哪些改變了我們?nèi)缃裆盍晳T的關(guān)鍵事件。

          1931 年 1 月 26 日:日本首批計算機的制造者 Eiichi Goto 出生

          圖源:維基百科

          后藤英一(Eiichi Goto)出生于 1931 年 1 月 26 日,他是日本計算機科學家,日本第一臺通用計算機的制造者。后藤出生于東京澀谷,1953 年畢業(yè)于成慶高中后,就讀于東京大學。在高橋英壽的指導下,他繼續(xù)在東京攻讀物理學研究生課程,并于 1962 年獲得博士學位。1959 年,他成為東京大學的教員。1968 年,他成為 RIKEN 信息科學實驗室的首席科學家,直到 1991 年。后藤于 2005 年 6 月 12 日因糖尿病并發(fā)癥逝世,享年 74 歲。

          1954 年,當他還是一名研究生時,后藤英一發(fā)明了 Parametron ,這是一種將鐵氧體磁芯與電容器相結(jié)合的電路元件,可產(chǎn)生可控制時序的電振蕩。這為當時用于構(gòu)建計算設(shè)備的真空管技術(shù)提供了一種替代方案。他于 1958 年基于參數(shù)的邏輯完成了日本制造的第一批通用計算機之一 PC-1 的構(gòu)建,不久之后,后藤在 1961 年訪問麻省理工學院期間設(shè)計了第一個時間最優(yōu)解決方案來解決細胞自動機設(shè)計問題。后藤因在 Parametron 和 PC-1 方面的工作獲得了 1959 年朝日獎,他于 1988 年獲得大河內(nèi)紀念技術(shù)獎,并于 1989 年因其在電子束成形方面的工作而被日本政府授予紫綬帶榮譽勛章。

          資料來源:維基百科

          1947 年 1 月 26 日:萬維網(wǎng)的共同發(fā)明人 Robert Cailliau 出生

          羅伯特·卡里奧(Robert Cailliau)出生于 1947 年 1 月 26 日,他是一位比利時信息工程師、計算機科學家。他與其 CERN 同事蒂姆·伯納斯-李一起開發(fā)了萬維網(wǎng)(WWW)。他設(shè)計了萬維網(wǎng)的歷史標志,于 1994 年在 CERN 組織了第一次國際萬維網(wǎng)會議,并于 1995 年幫助將 Web 開發(fā)從 CERN 轉(zhuǎn)移到了全球 Web 聯(lián)盟。卡里奧還與 James Gillies 博士一起撰寫了《萬維網(wǎng)是如何誕生的》,這是關(guān)于萬維網(wǎng)起源的第一本長篇著作。

          圖源:維基百科

          卡里奧出生于比利時通厄倫,1958 年他隨父母搬遷到安特衛(wèi)普。中學畢業(yè)后,他進入大學,于 1969 年以電子工程及機械工程方向的土木工程師專業(yè)畢業(yè)于根特大學。隨后,他又于 1971 年在密歇根大學獲得了計算機、信息與控制工程的理學碩士學位。在比利時軍隊服役期間,他維護了一個 Fortran 程序來模擬部隊調(diào)動。

          1974 年 12 月,他開始作為研究員在歐洲核子研究組織(CERN)的同步加速器(PS)部門工作,從事加速器控制系統(tǒng)的研究工作。1987 年 4 月,他離開 PS 部,成為數(shù)據(jù)處理部(Data Handling division)計算機系統(tǒng)辦公室(Office Computing Systems)的團體領(lǐng)袖。1989 年,蒂姆·伯納斯-李提出一個超文本系統(tǒng),目的是為訪問 CERN 文檔及其相關(guān)的文檔提供多種方式。伯納斯-李在 1990 年 9 月至 12 月創(chuàng)建了系統(tǒng),稱其為萬維網(wǎng)。這段時間內(nèi),卡里奧與伯納斯-李聯(lián)合發(fā)起了項目經(jīng)費的計劃。隨后,卡里奧成為項目的關(guān)鍵支持者。

          1993 年 12 月,他著手準備第一次國際萬維網(wǎng)會議,會議最終在 1994 年 5 月舉行。會議最終吸引了眾多網(wǎng)絡(luò)先驅(qū)來參加,達到 380 人,在網(wǎng)絡(luò)的發(fā)展史上是一個里程碑。會議促使國際萬維網(wǎng)會議委員會成立,從那時起每年都組織會議。1994 年,他與歐盟委員會啟動了“Web for Schools”項目,將網(wǎng)絡(luò)引入教育資源。在他協(xié)助將網(wǎng)絡(luò)發(fā)展的任務(wù)從 CERN 轉(zhuǎn)移到 W3C 后,他的時間都投入到公共通信的相關(guān)工作中。他于 2007 年 1 月提前從 CERN 退休。

          如今提到萬維網(wǎng),很多人會想到蒂姆·伯納斯-李,從而忽略卡里奧的名字,就好像提到蘋果時很多人會想到喬布斯而忘了沃茲。但在萬維網(wǎng)的歷史和將來,卡里奧都是一個無比重要的組成部分;他經(jīng)常在國際會議上發(fā)表許多主題演講,如今他計劃為全歐洲的互聯(lián)網(wǎng)做貢獻,致力于打造一個信息化的社會。你還知道哪些容易被忽視的互聯(lián)網(wǎng)名人嗎?歡迎在評論區(qū)分享。

          資料來源:維基百科、百度百科

          1983 年 1 月 26 日:曾經(jīng)的電子表格軟件霸主 Lotus 1-2-3 首次發(fā)布

          Lotus 1-2-3,是美國蓮花軟件公司(Lotus Software)于 1983 年起所推出的電子表格軟件,在 DOS 時期廣為個人電腦用戶所使用,是一套殺手級應(yīng)用軟件。但在 Windows 興起后,微軟鋪天蓋地營銷其 Microsoft Office 軟件,因此 Lotus 1-2-3 逐漸式微,退出了歷史舞臺。1980 年代后期,Lotus 1-2-3 因微軟推出“Excel”而受到極大威脅,1988 年微軟從蓮花手上奪下 12%的市場,還在不斷擴大戰(zhàn)果。Lotus 1-2-3 因為是用匯編語言撰寫的,在移植上有一定的難度,遲至二年后才推出。微軟在操作系統(tǒng)平臺的優(yōu)勢下,Excel 逐漸取代了 Lotus 1-2-3 ,成為主流的電子表格軟件。

          圖源:CSDN 下載自東方 IC

          美國蓮花軟件公司,是由米奇·卡普爾(Mitch Kapor)在 1982 年創(chuàng)建的軟件公司,他們推出的 Lotus 1-2-3 紅極一時,擊敗了微軟的 Multiplan,幾乎壟斷了電子表格。Lotus 1-2-3 的命名原因是它本身所擁有的三大功能:第一、強大的表格(spreadsheet)功能;第二、圖形集成功能;第三、簡易數(shù)據(jù)庫功能,故稱為 1-2-3,在當時這三種功能原本是由三個不同的軟件分別來執(zhí)行。事實上其本身還具有文字處理、文件管理的功能。

          1983 年 1 月 26 日,Lotus 1-2-3 首次發(fā)行,成為 IBM 兼容電腦的第一套殺手級應(yīng)用軟件,功能多而且運算速度快,很快就成為世界上第一個銷售超過 100 萬套的軟件,當時微軟的查爾斯·西蒙尼(Charles Simonyi)回憶說:“我第一次看到 Lotus 1-2-3,我就知道我們遇到麻煩了(I knew we were in trouble the first time I saw it.)”。第二版的 Lotus 1-2-3,被稱為 Symphony,也有人叫它 Lotus 1-2-3-4-5,因為它在 1-2-3 的基礎(chǔ)上又拼裝了文字處理和通信功能。

          在落敗于 Excel 后,1995 年 6 月 11 日,IBM 于以 35 億美元收購了蓮花公司。蓮花從此成為了 IBM 的一家子公司,而 Lotus 1-2-3 也成為了 IBM 公司的五大軟件產(chǎn)品線(Information Management、Lotus、Rational、Tivoli、WebSphere)之一。如今,IBM Lotus 1-2-3 已于 2013 年 6 月 11 日停止銷售,軟件支持服務(wù)持續(xù)到了 2014 年 9 月 30 日正式結(jié)束。和微軟爭鋒的軟件很多,但能像網(wǎng)景和火狐一樣存活下來,鳳凰涅槃,并非一件易事。

          資料來源:維基百科、百度百科

          2000 年 1 月 26 日:XHTML 問世

          XHTML,即“可擴展超文本標記語言”(Xtensible HyperText Markup Language),是一種標記語言,表現(xiàn)方式與超文本標記語言(HTML)類似,不過語法上更加嚴格。從繼承關(guān)系上講,HTML 是一種基于標準通用標記語言(SGML)的應(yīng)用,是一種非常靈活的指標語言,而 XHTML 則基于可擴展標記語言(XML),XML 是 SGML 的一個子集。XHTML 1.0 在 2000 年 1 月 26 日成為 W3C 的推薦標準。

          圖源:CSDN 下載自東方 IC

          XHTML 是 3 種 HTML 4 文件根據(jù) XML 1.0 標準重組而成的;于 2002 年 8 月發(fā)表的 XHTML 1.0 的建議中,W3C 指出 XHTML 家族將會是 Internet 的新階段。而轉(zhuǎn)換使用 XHTML 可以令開發(fā)人員接觸 XML 和其好處,并可以確保以 XHTML 開發(fā)的網(wǎng)頁于未來的兼容性。HTML 語法要求比較松散,這樣對網(wǎng)頁編寫者來說,比較方便,但對于機器來說,語言的語法越松散,處理起來就越困難,對于傳統(tǒng)的電腦來說,還有能力兼容松散語法,但對于許多其他設(shè)備,比如手機,難度就比較大。因此產(chǎn)生了由 DTD 定義規(guī)則,語法要求更加嚴格的 XHTML。

          大部分常見的瀏覽器都可以正確地解析 XHTML,即使老一點的瀏覽器,XHTML 作為 HTML 的一個子集,許多也可以解析。也就是說,幾乎所有的網(wǎng)頁瀏覽器在正確解析 HTML 的同時,可兼容 XHTML。當然,從 HTML 完全轉(zhuǎn)移到 XHTML,還需要一些過程。總而言之,XHTML5 并非可擴展 HTML 的后繼語言,而是對 XML 序列化的 HTML5 的稱呼,延續(xù)了一部分原本 XHTML 的精神而加入 HTML5,成為 HTML5 規(guī)格的一部分。XHTML 1.1 就是 XHTML 最后的獨立標準,2.0 止于草案階段。XHTML5 則是屬于 HTML5 標準的一部分,且名稱已改為“以 XML 序列化的 HTML5”,而非“可擴展的 HTML”。如今,XHTML5 比起 HTML5 并非主流,W3C 也建議大多數(shù)人使用 HTML 語法,而不是 XHTML 語法。

          資料來源:維基百科、百度百科

          2011 年 1 月 26 日:知乎上線

          知乎是一家創(chuàng)立于 2011 年 1 月 26 日的中國社會化問答網(wǎng)站,產(chǎn)品形態(tài)與美國在線問答網(wǎng)站 Quora 類似。“知乎”在文言文中意為“知道嗎”,2012 年 2 月底,知乎使用“發(fā)現(xiàn)更大的世界”作為其宣傳口號。截至 2017 年 9 月 20 日,知乎注冊用戶數(shù)超 1 億 ,日活躍用戶量達 2600 萬,人均日訪問時長 1 小時,月瀏覽量 180 億。截至 2016 年 5 月,知乎累計產(chǎn)生了 1000 萬個提問、3400 萬個回答和 3500 萬個贊同。2021 年至紐交所上市,不過仍未盈利。

          知乎由北京智者天下科技有限公司所持有,其法律代表人是李大海。智者天下亦開發(fā)了包括 Android、iOS 平臺的手機“知乎客戶端”、“知乎群組”、“知乎日報”與“公益壹點通”四款手機應(yīng)用程序。如今,在挖掘優(yōu)質(zhì)創(chuàng)作會員與投入自有內(nèi)容的同時,隨著多樣性的社群文化增加,知乎越來越類似于 Reddit 等同好論壇,成為了許多人的互聯(lián)網(wǎng)社交網(wǎng)站。

          圖源:CSDN 下載自東方 IC

          知乎團隊成員在創(chuàng)立初期只有十多人,周源和其同事李申申是知乎的聯(lián)合創(chuàng)始人,分別擔任知乎的 CEO 和 CTO;原創(chuàng)新工場的投資經(jīng)理黃繼新?lián)沃醯?COO;原網(wǎng)易微博產(chǎn)品經(jīng)理黃海均擔任知乎的產(chǎn)品經(jīng)理;成遠和胡維則負責知乎的產(chǎn)品運營。隨著知乎的發(fā)展,知乎用戶被稱為知友,知乎團隊人數(shù)也逐漸增多。知乎在創(chuàng)建初期邀請了大量互聯(lián)網(wǎng)界的知名人士,如愿創(chuàng)建起了良好的基礎(chǔ)氛圍。在運營的過程中,知乎也通過“贊同、反對、沒有幫助”等本身的投票功能,以及外部輸出的知乎閱讀、知乎日報等方式鼓勵用戶共享高質(zhì)量的內(nèi)容。

          知乎中出現(xiàn)大量有一定特征的提問標題,如“如何評價/看待 XXX”、“XXX 是怎樣的體驗/怎樣一番體驗”等。此外,回答中的“謝邀”(感謝其他網(wǎng)友邀請回答問題)、“以上”(用于結(jié)尾表示回答完畢)等也是知乎體的特征之一。知乎的注冊用戶可以面向社群提出問題,也可以向指定的用戶提出問題。每個用戶在首頁都可以看到自己所關(guān)注用戶所回答、關(guān)注、贊同的問題,也可以看到所關(guān)注話題的更新。用戶還可以邀請至多六名用戶來回答某個問題。為了讓用戶及時獲取自己感興趣的內(nèi)容,知乎員工會收集一些用戶感興趣的高質(zhì)量回答,通過“每周精選”或“知乎閱讀”的方式推送給用戶。同時其領(lǐng)域功能能讓用戶系統(tǒng)地發(fā)現(xiàn)所感興趣領(lǐng)域的優(yōu)質(zhì)問答。

          隨著互聯(lián)網(wǎng)的發(fā)展,越來越多的人可以通過網(wǎng)絡(luò)了解到以前不知道的知識;而問答網(wǎng)站作為以“人與人”交互的平臺,讓許多普通人也有了和專家在網(wǎng)絡(luò)上面對面的機會,很多時候可以提供搜索引擎無法找到的偏僻知識。你認為在不久的未來里,人工智能和大數(shù)據(jù)會讓搜索引擎發(fā)展到比人類回答專業(yè)知識還快嗎?歡迎參與本期投票,在評論區(qū)分享你的真知灼見。

          資料來源:維基百科、百度百科

          2014 年 1 月 26 日:Google 收購 DeepMind

          DeepMind 是一家英國的人工智能公司。公司由 Demis Hassabis、Shane Legg 和 Mustafa Suleyman 于 2010 年創(chuàng)立,最初名稱是 DeepMind 科技(DeepMind Technologies Limited),在 2014 年被谷歌收購。DeepMind 公司總部位于倫敦,在加拿大、法國和美國。2015 年,DeepMind 成為谷歌母公司 Alphabet 的全資子公司。

          圖源:CSDN 下載自東方 IC

          DeepMind 于 2014 年開始開發(fā)人工智能圍棋軟件 AlphaGo,2016 年,DeepMind 的 AlphaGo 程序在五場比賽中擊敗了人類職業(yè)圍棋選手、世界冠軍李世石。2017 年 10 月 19 日,AlphaGo 的團隊在《自然》雜志上發(fā)表了一篇文章,介紹了 AlphaGo Zero,這是一個沒有用到人類數(shù)據(jù)的版本,比以前任何擊敗人類的版本都要強大。通過跟自己對戰(zhàn),AlphaGo Zero 經(jīng)過 3 天的學習,以 100:0 的成績超越了 AlphaGo Lee 的實力,21 天后達到了 AlphaGo Master 的水平,并在 40 天內(nèi)超過了所有之前的版本。2019 年 1 月 25 日,DeepMind 人工智能 AlphaStar 在《星際爭霸 II》以 10:1 戰(zhàn)勝人類職業(yè)玩家,改變了許多人對于“人工智能無法完成團隊協(xié)作游戲”的印象。

          2016 年,DeepMind 將其人工智能轉(zhuǎn)向蛋白質(zhì)折疊,這是科學中最棘手的問題之一。2018 年 12 月,DeepMind 的 AlphaFold 通過成功預(yù)測 43 種蛋白質(zhì)中的 25 種最準確的結(jié)構(gòu),贏得了第 13 次蛋白質(zhì)結(jié)構(gòu)預(yù)測技術(shù)關(guān)鍵評估(CASP)。“這是一個燈塔項目,我們第一次在人力和資源方面對一個基本的、非常重要的、現(xiàn)實世界的科學問題進行重大投資,”哈薩比斯對衛(wèi)報說。2020 年,在第 14 屆 CASP 中,AlphaFold 的預(yù)測達到了與實驗室技術(shù)相當?shù)臏蚀_度分數(shù)。科學評審小組之一安德烈·克里什塔福維奇博士將這一成就描述為“真正了不起的”,并表示預(yù)測蛋白質(zhì)如何折疊的問題已“基本解決”。

          繼 AlphaGo 之后,Google DeepMind 首席執(zhí)行官 Demis Hassabis 曾表示將研究用人工智能與人類玩其他游戲,例如即時戰(zhàn)略游戲《星際爭霸 II》(StarCraft II)深度 AI 如果能直接使用在其他各種不同領(lǐng)域,除了未來能玩不同的游戲外,例如自動駕駛、投資顧問、音樂評論、甚至司法判決等等目前需要人腦才能處理的工作,基本上也可以直接使用相同的神經(jīng)網(wǎng)絡(luò)去學而習得與人類相同的思考力。你對于人工智能的極限都有哪些遐想呢?歡迎在評論區(qū)分享你的真知灼見。

          【歡迎投稿】以史為鏡,可以知興替。計算機科學發(fā)展至今,有許多至關(guān)重要的事件、人物,歡迎所有朋友一起共建「歷史上的今天」,投稿郵箱:tangxy@csdn.net 。

          新程序員003》正式上市,50余位技術(shù)專家共同創(chuàng)作,云原生和數(shù)字化的開發(fā)者們的一本技術(shù)精選圖書。內(nèi)容既有發(fā)展趨勢及方法論結(jié)構(gòu),華為、阿里、字節(jié)跳動、網(wǎng)易、快手、微軟、亞馬遜、英特爾、西門子、施耐德等30多家知名公司云原生和數(shù)字化一手實戰(zhàn)經(jīng)驗!

          件項目實訓及課程設(shè)計指導——如何應(yīng)用XML+XSLT技術(shù)分離Web表示層數(shù)據(jù)和樣式

          1、"XML+XSLT"技術(shù)在J2EE技術(shù)平臺中的應(yīng)用

          Java語言及相關(guān)的應(yīng)用技術(shù)的產(chǎn)生解決了跨平臺的軟件應(yīng)用系統(tǒng)的開發(fā),但沒有解決如何實現(xiàn)跨平臺的數(shù)據(jù)交換問題。在傳統(tǒng)的軟件應(yīng)用系統(tǒng)中,為了能夠?qū)崿F(xiàn)在不同的系統(tǒng)平臺之間交換數(shù)據(jù)、同時還要保證數(shù)據(jù)的完整性,是相對比較麻煩的一件事情。

          基于此應(yīng)用的目的和要求,誕生了XML(eXtensible Markup Language,可擴展標記語言)技術(shù)。應(yīng)用XML語言可以實現(xiàn)軟件應(yīng)用系統(tǒng)中的"內(nèi)容"與"表現(xiàn)"相互分離,并且XML還是一種可擴展的標簽語言。

          如下示例圖中的代碼為一個定義學生信息的XML格式文檔示例,讀者從此示例中可以了解到XML格式文檔只定義數(shù)據(jù)內(nèi)容(或者應(yīng)用系統(tǒng)處理的最終結(jié)果),而這些數(shù)據(jù)或者結(jié)果最終在什么終端設(shè)備顯示、以及以什么風格顯示都沒有定義。

          基于XML語言及應(yīng)用技術(shù)的XSLT(Extensible Stylesheet Language Transformations,擴展樣式表轉(zhuǎn)換語言)的主要作用是將XML由一種格式轉(zhuǎn)換為另一種格式(當然,也可以為其它格式,如HTML網(wǎng)頁,純文字等),而在J2EE Web應(yīng)用系統(tǒng)的開發(fā)實現(xiàn)中,應(yīng)用XSLT技術(shù)能夠?qū)崿F(xiàn)將XML格式的源文檔通過轉(zhuǎn)換引擎并按照XSL(eXtensible Stylesheet Lanaguage,擴展樣式表語言)模板的格式最終轉(zhuǎn)換輸出目標HTML格式的文檔。

          如下示例圖中的代碼為某個XSLT文檔文件的內(nèi)容,其中包含有<xsl:stylesheet>、<xsl:template>等標簽,同時在<xsl:template></xsl:template>標簽內(nèi)包含有一個完整的HTML文件所應(yīng)該具有的標簽。這些標簽都起什么作用?源XML文檔最終在瀏覽器中的顯示結(jié)果如何?

          由于XSLT文檔文件本身也是一個 XML格式的文檔,因此它也總是由如下的XML聲明語句起始:<?xml version="1.0" encoding="gb2312"?>

          但由于本文章的篇幅有限,讀者如果需要詳細了解和學習XML、XSLT和XHTML等相關(guān)的語法、技術(shù)和應(yīng)用等,可以參考作者的《J2EE Web核心技術(shù)——XHTML與XML應(yīng)用開發(fā)》一書中相關(guān)章節(jié)內(nèi)容。

          讀者也許還會有許多的疑問,比如為什么要多此一舉?請讀者保持耐心,繼續(xù)往下閱讀。

          2、XSL技術(shù)概述及在J2EE系統(tǒng)平臺中的應(yīng)用

          (1)XSL是什么

          XSL就是可擴展樣式表語言(eXtensible Stylesheet Lanaguage),XSL是參考SGML(Standard Generalized Markup Language,標準通用標記語言)中的DSSSL(Document Style Semanticsand Specification Language,文檔樣式語義和規(guī)范語言,它主要是用來設(shè)置SGML的表現(xiàn)樣式)而設(shè)計的。

          (2)為什么要提供XSL技術(shù)

          盡管"CSS+Div"能夠為Web應(yīng)用系統(tǒng)的頁面開發(fā)人員分離Web頁面中的結(jié)構(gòu)和風格,從而實現(xiàn)分離Web頁面中的數(shù)據(jù)和表現(xiàn)。但如果其中的數(shù)據(jù)是采用XML格式表示,此時如果再繼續(xù)采用CSS層疊樣式表技術(shù)來為該XML格式文檔數(shù)據(jù)設(shè)置表現(xiàn)樣式,由于CSS層疊樣式表采用的是與XML完全不同的一套語法規(guī)則定義,無法使用相同的XML解析器進行處理和解析,這為軟件應(yīng)用系統(tǒng)項目開發(fā)帶來了許多額外的負擔。

          最初設(shè)計XSL的主要目的就是希望采用XML格式的語法規(guī)則提供一種為XML文檔設(shè)置表現(xiàn)樣式的新方法。而CSS的主要問題是由于沒有邏輯控制的能力——CSS不能重新排序文檔中的元素、也不能判斷和控制哪個元素被顯示、哪個不被顯示、當然也不能統(tǒng)計計算元素中的數(shù)據(jù)等功能要求。

          因此CSS層疊樣式表技術(shù)一般只適合用于輸出固定內(nèi)容的最終Web頁面文檔,但CSS層疊樣式表技術(shù)的主要優(yōu)點是簡潔、消耗系統(tǒng)資源少;而XSLT雖然功能強大,但因為要重新索引XML結(jié)構(gòu)樹,所以消耗系統(tǒng)內(nèi)存量比較多。

          在企業(yè)級的軟件應(yīng)用系統(tǒng)開發(fā)中,一般常常將CSS和XSLT兩者相互結(jié)合使用。比如在Web服務(wù)器端用XSLT處理相關(guān)的文檔,而在客戶端則用CSS層疊樣式表技術(shù)來控制數(shù)據(jù)在瀏覽器端的最終顯示風格,這樣的設(shè)計方案能夠大大地減少響應(yīng)時間。

          3、XSL技術(shù)主要包括兩個組成部分

          XSL技術(shù)主要包括兩個組成部分:XSLT(eXtensible Stylesheet Language Transformation)和XSL-FO(XSL Formatting Object)。

          其中的XSLT主要是實現(xiàn)轉(zhuǎn)換XML格式的文檔,而XSL-FO主要是格式化XML文檔。其中XSL-FO的作用就類似CSS層疊樣式表技術(shù)在HTML頁面中的作用,但作者在本文中重點為讀者介紹XSLT相關(guān)的技術(shù)及應(yīng)用。

          因此,XSL從本質(zhì)上可以看著為是一種可以將XML轉(zhuǎn)化成其它類型語言的語言、一種可以過濾和選擇XML數(shù)據(jù)的語言、一種能夠格式化XML數(shù)據(jù)的語言。

          4、XSLT主要是面向轉(zhuǎn)換類型的應(yīng)用

          XSLT的主要作用是將XML文檔數(shù)據(jù)內(nèi)容由一種格式轉(zhuǎn)換為另一種格式——比如,將XML格式的文檔轉(zhuǎn)換為HTML/XHTML(或者WML)等格式的文檔是目前XSLT應(yīng)用最為廣泛的應(yīng)用領(lǐng)域。

          為什么要應(yīng)用XSLT及相關(guān)的技術(shù)?因為XML格式的數(shù)據(jù)文檔能夠便于交換但不便于人類的閱讀和理解、特別是機器自動化地閱讀。因此如何能夠按照人類的要求顯示XML格式文檔中的數(shù)據(jù)?如何實現(xiàn)將同一個XML格式文檔中的數(shù)據(jù)在不同的顯示平臺中顯示輸出?

          5、XSLT數(shù)據(jù)格式轉(zhuǎn)換的基本實現(xiàn)原理

          數(shù)據(jù)格式轉(zhuǎn)換的重要思想是要把XML格式文檔視為一種樹形結(jié)構(gòu),轉(zhuǎn)換的過程其實就是從源XML格式文檔樹生成結(jié)果樹的過程。其中的XSL樣式單定義了源XML格式文檔樹和結(jié)果樹中對應(yīng)部分的轉(zhuǎn)換規(guī)則,在每條規(guī)則中包含了一個模板,并對應(yīng)著一種模式——模板定義了轉(zhuǎn)換的結(jié)果和轉(zhuǎn)換的基本規(guī)則,而模式則規(guī)定了需要進行轉(zhuǎn)換的元素或?qū)傩詫ο蟆?/p>

          6、XSLT數(shù)據(jù)格式轉(zhuǎn)換的實現(xiàn)過程

          首先,將XML格式文檔轉(zhuǎn)換為DOM(Document Object Model,文檔對象模型)樹結(jié)構(gòu),這主要是利用XSLT來實現(xiàn)——XSLT處理器首先要做的是通過XML解析器(比如DOM或SAX)技術(shù)讀取XML格式文檔中的各個標簽和數(shù)據(jù),并將XML樹狀結(jié)構(gòu)重新整理和組合產(chǎn)生出一個臨時的樹狀結(jié)構(gòu),這個樹狀結(jié)構(gòu)稱為XML文檔結(jié)果樹。

          其次,再對轉(zhuǎn)換后的DOM樹進行格式化并轉(zhuǎn)換為其它的目標形式,這主要是利用XSL-FO來實現(xiàn)。XSL處理程序?qū)⑦@些數(shù)據(jù)轉(zhuǎn)換(也就是格式化過程)為另一種格式良好的XML文件(如:WML、HTML、VoiceXML等)。

          目前在微軟IE瀏覽器中已經(jīng)內(nèi)嵌有實現(xiàn)這個轉(zhuǎn)換過程的XML處理器程序。歡迎讀者繼續(xù)閱讀作者的另一篇文章《軟件項目實訓及課程設(shè)計指導--應(yīng)用XML+XSLT技術(shù)分離Web表示層數(shù)據(jù)和樣式示例》可以詳細學習和了解如何在軟件應(yīng)用系統(tǒng)開發(fā)中應(yīng)用XML+XSLT技術(shù)。

          7、應(yīng)用XSLT實現(xiàn)對XML格式文檔中的數(shù)據(jù)轉(zhuǎn)換和合并的應(yīng)用示例

          為了能夠讓讀者對"XML+XSLT"技術(shù)在企業(yè)級軟件應(yīng)用系統(tǒng)開發(fā)中的應(yīng)用有感性的認識,作者在下文中給出一個典型示例加以說明。

          在下面示例中的XML格式文檔中的"學生信息"節(jié)點中有多個"班級"節(jié)點,可以通過XSLT中的<xsl:for-each>標簽把這些節(jié)點數(shù)據(jù)在一個表格單元格中顯示出來,從而產(chǎn)生出合并數(shù)據(jù)的應(yīng)用效果。當然,也可以實現(xiàn)其它的應(yīng)用效果,讀者可以自行實現(xiàn)。

          (1)示例中所對應(yīng)的XML格式文檔

          該XML文檔文件名稱為student.xml,其中在<?xml-stylesheet?>標簽中通過href屬性指定對應(yīng)的XSLT文件,該文件名稱為student.xsl。

          <?xml version="1.0" encoding="GB2312" standalone="yes" ?>
          <?xml-stylesheet type="text/xsl" href="student.xsl" ?>
          <軟件學院學生信息>
                <學生信息 性別="男">
                      <姓名>張三</姓名>
                      <出生日期>1987/10/18</出生日期>
                      <專業(yè)>軟件工程</專業(yè)>
                      <班級 方向="J2EE軟件開發(fā)">軟件1班</班級>
                      <班級>9教東201</班級>
                </學生信息>
                <學生信息 性別="女">
                      <姓名>李四</姓名>
                      <出生日期>1988/2/18</出生日期>
                      <專業(yè)>軟件工程</專業(yè)>
                      <班級 方向="數(shù)字媒體方向">軟件2班</班級>
                      <班級>9教東202</班級>
                </學生信息>
          </軟件學院學生信息>

          (2)示例中的XML文檔所對應(yīng)的XSLT文檔(student.xsl) 文件

          在student.xsl 文件中應(yīng)用了XSL語言中的一些標簽,而XSLT文件中的標簽語法大致可分為如下的三種類型:

          1)選擇模式,如<xsl:for-each>、<xsl:value-of>和 <xsl:apply-templates>等標簽,這些選擇模式的標簽語句將數(shù)據(jù)從XML文檔中提取出來,是一種簡單獲得數(shù)據(jù)的方法。在這些標簽中都有一個select屬性,選取XML文檔中特定的節(jié)點名的數(shù)據(jù)。

          2)測試(識別)模式,如<xsl:if> 和<xsl:when>等標簽,類似于編程語言中的條件語句,主要是用于條件判斷和識別等用途。

          3)匹配模式,如<xsl:template>標簽,它用于構(gòu)建和定義一個模板。該標簽中的match 屬性主要是用于關(guān)聯(lián) XML文檔中的標簽元素和轉(zhuǎn)換模板,但match 屬性的值是 XPath (XML Path Language,XML路徑語言)表達式(比如match="/" 則是定義整個XML格式文檔);位于<xsl:template> 標簽元素內(nèi)部的內(nèi)容則定義了寫到輸出結(jié)果的 HTML標簽代碼。

          <?xml version="1.0" encoding="gb2312" ?>
          <xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
              <xsl:template match="/">
                    <html>
                    <head>
                    <title>XX交通大學軟件學院學生信息</title>
                    </head>
                    <body>
                    <xsl:apply-templates/>
                    </body>
                    </html>
              </xsl:template>
              <xsl:template match="軟件學院學生信息">
                    <h3>下面為XX交通大學軟件學院學生信息表</h3>
                    <table border="1">
                    <th>姓名</th>
                    <th>性別</th>
                    <th>出生日期</th>
                    <th>專業(yè)</th>
                    <th>班級</th>
                    <th>專業(yè)方向</th>
                    <xsl:apply-templates/>
                    </table>
              </xsl:template>
              <xsl:template match="學生信息">
                    <tr>
                    <td><xsl:value-of select="姓名"/></td>
                    <td><xsl:value-of select="@性別"/></td>
                    <td><xsl:value-of select="出生日期"/></td>
                    <td><xsl:value-of select="專業(yè)"/></td>
                    <td>
                    <xsl:for-each select="班級">
                    <xsl:value-of />
                    </xsl:for-each>
                    </td>
                    <xsl:apply-templates/>
                    </tr>
              </xsl:template>
              <xsl:template match="班級">
                    <td><xsl:value-of select="@方向"/></td>
              </xsl:template>
          </xsl:stylesheet>

          在student.xsl 文件中應(yīng)用了<xsl:apply-templates> 標簽元素產(chǎn)生模板嵌套的應(yīng)用效果,因為<xsl:apply-templates> 標簽元素可把一個模板應(yīng)用于當前的標簽元素或者當前標簽元素的子節(jié)點中。

          如果向 <xsl:apply-templates> 標簽元素添加一個 select 屬性,則此標簽元素就會僅僅處理與由其select 屬性所定義的XML標簽中屬性值相匹配的XML標簽元素,從而可以過濾XML標簽。

          (3)本示例在Web瀏覽器中最終執(zhí)行的結(jié)果

          如何應(yīng)用CSS+Div分離Web表示層數(shù)據(jù)處理邏輯和展現(xiàn)邏輯

          如何應(yīng)用策略設(shè)計模式分離JDBC數(shù)據(jù)庫連接中的外部環(huán)境信息

          如何應(yīng)用策略設(shè)計模式的思想設(shè)計通用的數(shù)據(jù)庫連接類

          如何正確地創(chuàng)建和銷毀軟件應(yīng)用系統(tǒng)中JDBC數(shù)據(jù)庫連接對象實例

          如何應(yīng)用觀察者設(shè)計模式重構(gòu)系統(tǒng)中日志處理功能實現(xiàn)的程序代碼


          主站蜘蛛池模板: 成人免费观看一区二区| 精彩视频一区二区三区| 久久99精品波多结衣一区| 一区二区三区视频免费| 精品国产一区二区三区久久| 亚洲一区无码中文字幕乱码| 国产精品亚洲一区二区三区久久 | 蜜桃AV抽搐高潮一区二区| 日韩制服国产精品一区| 免费萌白酱国产一区二区| 国产精品一区二区不卡| 亚洲永久无码3D动漫一区| 日本一区高清视频| 精品国产一区二区三区麻豆| 国产在线无码视频一区二区三区 | 国产亚洲日韩一区二区三区 | 日韩精品一区二区三区色欲AV| 精品国产一区二区三区免费看| 亚洲一区二区三区影院| 日本免费一区尤物| 国产aⅴ精品一区二区三区久久 | 亚洲av色香蕉一区二区三区| 亚洲Av无码一区二区二三区 | 中文字幕在线无码一区二区三区| 国产一区二区三区免费看| 国产成人一区二区在线不卡| 日韩美女视频一区| 国产精品一区二区四区| 日本v片免费一区二区三区| 亚洲性色精品一区二区在线| 中文字幕日韩丝袜一区| 日韩一区二区在线播放| 在线观看国产一区二三区| 韩国资源视频一区二区三区| 国产精品一区在线观看你懂的| 一本AV高清一区二区三区| 日本视频一区在线观看免费| 精品国产一区二区三区av片| 久久国产三级无码一区二区| 精品一区二区三区无码免费视频 | 国产成人精品一区二区A片带套|