• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 87  文章 - 279  trackbacks - 0
            <2007年9月>
            2627282930311
            2345678
            9101112131415
            16171819202122
            23242526272829
            30123456

            潛心看書研究!

            常用鏈接

            留言簿(19)

            隨筆分類(81)

            文章分類(89)

            相冊

            ACM OJ

            My friends

            搜索

            •  

            積分與排名

            • 積分 - 219046
            • 排名 - 118

            最新評論

            閱讀排行榜

            評論排行榜

            Java與XML讀寫之DOM篇
            DOM
            初步
            DOM是Document Object Model的縮寫,即文檔對象模型。前面說過,XML將數(shù)據(jù)組織為一顆樹,
            所以DOM就是對這顆樹的一個(gè)對象描敘。通俗的說,就是通過解析XML文檔,為XML文檔在
            邏輯上建立一個(gè)樹模型,樹的節(jié)點(diǎn)是一個(gè)個(gè)對象。我們通過存取這些對象就能夠存取XML文檔
            的內(nèi)容。
            下面我們來看一個(gè)簡單的例子,看看在DOM中,我們是如何來操作一個(gè)XML文檔的。
            這是一個(gè)XML文檔,也是我們要操作的對象:
            下面,我們需要把這個(gè)文檔的內(nèi)容解析到一個(gè)個(gè)的Java對象中去供程序使用,利用JAXP,我們
            只需幾行代碼就能做到這一點(diǎn)。首先,我們需要建立一個(gè)解析器工廠,以利用這個(gè)工廠來獲得
            一個(gè)具體的解析器對象:
            我們在這里使用DocumentBuilderFacotry的目的是為了創(chuàng)建與具體解析器無關(guān)的程序,當(dāng)
            DocumentBuilderFactory類的靜態(tài)方法newInstance()被調(diào)用時(shí),它根據(jù)一個(gè)系統(tǒng)變量來決定具體
            使用哪一個(gè)解析器。又因?yàn)樗械慕馕銎鞫挤挠贘AXP所定義的接口,所以無論具體使用哪一
            個(gè)解析器,代碼都是一樣的。所以當(dāng)在不同的解析器之間進(jìn)行切換時(shí),只需要更改系統(tǒng)變量的
            值,而不用更改任何代碼。這就是工廠所帶來的好處。這個(gè)工廠模式的具體實(shí)現(xiàn),可以參看下
            面的類圖。
            當(dāng)獲得一個(gè)工廠對象后, 使用它的靜態(tài)方法newDocumentBuilder() 方法可以獲得一個(gè)
            DocumentBuilder對象,這個(gè)對象代表了具體的DOM解析器。但具體是哪一種解析器,微軟的或
            者IBM的,對于程序而言并不重要。
            然后,我們就可以利用這個(gè)解析器來對XML文檔進(jìn)行解析了:
            DocumentBuilder的parse()方法接受一個(gè)XML文檔名作為輸入?yún)?shù),返回一個(gè)Document對象,這
            <?xml version="1.0" encoding="UTF-8"?>
            <messages>
            <message>Good-bye serialization, hello Java!</message>
            </messages>
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse("c:/xml/message.xml");
            個(gè)Document對象就代表了一個(gè)XML文檔的樹模型。以后所有的對XML文檔的操作,都與解析器
            無關(guān),直接在這個(gè)Document對象上進(jìn)行操作就可以了。而具體對Document操作的方法,就是由
            DOM所定義的了。
            Jaxp支持W3C所推薦的DOM 2。如果你對DOM很熟悉,那么下面的內(nèi)容就很簡單了:只需要按
            照DOM的規(guī)范來進(jìn)行方法調(diào)用就可以。當(dāng)然,如果你對DOM不清楚,也不用著急,后面我們
            會有詳細(xì)的介紹。在這兒,你所要知道并牢記的是:DOM是用來描敘XML文檔中的數(shù)據(jù)的模型,
            引入DOM的全部原因就是為了用這個(gè)模型來操作XML文檔的中的數(shù)據(jù)。DOM規(guī)范中定義有節(jié)
            點(diǎn)(即對象)、屬性和方法,我們通過這些節(jié)點(diǎn)的存取來存取XML的數(shù)據(jù)。
            從上面得到的Document對象開始,我們就可以開始我們的DOM之旅了。使用Document對象的
            getElementsByTagName()方法,我們可以得到一個(gè)NodeList對象,一個(gè)Node對象代表了一個(gè)XML
            文檔中的一個(gè)標(biāo)簽元素,而NodeList對象,觀其名而知其意,所代表的是一個(gè)Node對象的列表:
            我們通過這樣一條語句所得到的是XML文檔中所有<message>標(biāo)簽對應(yīng)的Node對象的一個(gè)列
            表。然后,我們可以使用NodeList對象的item()方法來得到列表中的每一個(gè)Node對象:
            當(dāng)一個(gè)Node對象被建立之后,保存在XML文檔中的數(shù)據(jù)就被提取出來并封裝在這個(gè)Node中了。
            NodeList nl = doc.getElementsByTagName("message");
            Node my_node = nl.item(0);
            在這個(gè)例子中,要提取Message標(biāo)簽內(nèi)的內(nèi)容,我們通常會使用Node對象的getNodeValue()方法:
            請注意,這里還使用了一個(gè)getFirstChild()方法來獲得message下面的第一個(gè)子Node對象。雖然在
            message 標(biāo)簽下面除了文本外并沒有其它子標(biāo)簽或者屬性, 但是我們堅(jiān)持在這里使用
            getFirseChild()方法,這主要和W3C對DOM的定義有關(guān)。W3C把標(biāo)簽內(nèi)的文本部分也定義成一
            個(gè)Node,所以先要得到代表文本的那個(gè)Node,我們才能夠使用getNodeValue()來獲取文本的內(nèi)
            容。
            現(xiàn)在,既然我們已經(jīng)能夠從XML文件中提取出數(shù)據(jù)了,我們就可以把這些數(shù)據(jù)用在合適的地方,
            來構(gòu)筑應(yīng)用程序。
            下面的內(nèi)容,我們將更多的關(guān)注DOM,為DOM作一個(gè)較為詳細(xì)的解析,使我們使用起來更為
            得心應(yīng)手。
            DOM
            詳解
            DOM的基本對象有5個(gè):Document,Node,NodeList,Element和Attr。下面就這些對象的功
            能和實(shí)現(xiàn)的方法作一個(gè)大致的介紹。
            Document對象代表了整個(gè)XML的文檔,所有其它的Node,都以一定的順序包含在Document
            String message = my_node.getFirstChild().getNodeValue();
            1.基本的DOM對象
            對象之內(nèi),排列成一個(gè)樹形的結(jié)構(gòu),程序員可以通過遍歷這顆樹來得到XML文檔的所有的內(nèi)容,
            這也是對XML文檔操作的起點(diǎn)。我們總是先通過解析XML源文件而得到一個(gè)Document對象,
            然后再來執(zhí)行后續(xù)的操作。此外,Document還包含了創(chuàng)建其它節(jié)點(diǎn)的方法,比如createAttribut()
            用來創(chuàng)建一個(gè)Attr對象。它所包含的主要的方法有:
            createAttribute(String):用給定的屬性名創(chuàng)建一個(gè)Attr對象,并可在其后使用setAttributeNode
            方法來放置在某一個(gè)Element對象上面。
            createElement(String):用給定的標(biāo)簽名創(chuàng)建一個(gè)Element對象,代表XML文檔中的一個(gè)標(biāo)簽,
            然后就可以在這個(gè)Element對象上添加屬性或進(jìn)行其它的操作。
            createTextNode(String):用給定的字符串創(chuàng)建一個(gè)Text對象,Text對象代表了標(biāo)簽或者屬性中
            所包含的純文本字符串。如果在一個(gè)標(biāo)簽內(nèi)沒有其它的標(biāo)簽,那么標(biāo)簽內(nèi)的文本所代表的Text
            對象是這個(gè)Element對象的唯一子對象。
            getElementsByTagName(String):返回一個(gè)NodeList對象,它包含了所有給定標(biāo)簽名字的標(biāo)簽。
            getDocumentElement():返回一個(gè)代表這個(gè)DOM樹的根節(jié)點(diǎn)的Element對象,也就是代表XML
            文檔根元素的那個(gè)對象。
            Node對象是DOM結(jié)構(gòu)中最為基本的對象,代表了文檔樹中的一個(gè)抽象的節(jié)點(diǎn)。在實(shí)際使用的
            時(shí)候,很少會真正的用到Node這個(gè)對象,而是用到諸如Element、Attr、Text等Node對象的子
            對象來操作文檔。Node對象為這些對象提供了一個(gè)抽象的、公共的根。雖然在Node對象中定
            義了對其子節(jié)點(diǎn)進(jìn)行存取的方法,但是有一些Node子對象,比如Text對象,它并不存在子節(jié)點(diǎn),
            這一點(diǎn)是要注意的。Node對象所包含的主要的方法有:
            appendChild(org.w3c.dom.Node):為這個(gè)節(jié)點(diǎn)添加一個(gè)子節(jié)點(diǎn),并放在所有子節(jié)點(diǎn)的最后,
            如果這個(gè)子節(jié)點(diǎn)已經(jīng)存在,則先把它刪掉再添加進(jìn)去。
            getFirstChild():如果節(jié)點(diǎn)存在子節(jié)點(diǎn),則返回第一個(gè)子節(jié)點(diǎn),對等的,還有g(shù)etLastChild()方法
            返回最后一個(gè)子節(jié)點(diǎn)。
            getNextSibling() : 返回在DOM 樹中這個(gè)節(jié)點(diǎn)的下一個(gè)兄弟節(jié)點(diǎn), 對等的, 還有
            getPreviousSibling()方法返回其前一個(gè)兄弟節(jié)點(diǎn)。
            getNodeName():根據(jù)節(jié)點(diǎn)的類型返回節(jié)點(diǎn)的名稱。
            getNodeType():返回節(jié)點(diǎn)的類型。
            getNodeValue():返回節(jié)點(diǎn)的值。
            hasChildNodes():判斷是不是存在有子節(jié)點(diǎn)。
            hasAttributes():判斷這個(gè)節(jié)點(diǎn)是否存在有屬性。
            getOwnerDocument():返回節(jié)點(diǎn)所處的Document對象。
            insertBefore(org.w3c.dom.Node new,org.w3c.dom.Node ref):在給定的一個(gè)子對象前再插入
            一個(gè)子對象。
            removeChild(org.w3c.dom.Node):刪除給定的子節(jié)點(diǎn)對象。
            replaceChild(org.w3c.dom.Node new,org.w3c.dom.Node old):用一個(gè)新的Node對象代替給
            定的子節(jié)點(diǎn)對象。
            NodeList對象,顧名思義,就是代表了一個(gè)包含了一個(gè)或者多個(gè)Node的列表。可以簡單的把它
            看成一個(gè)Node的數(shù)組,我們可以通過方法來獲得列表中的元素:
            GetLength():返回列表的長度。
            Item(int):返回指定位置的Node對象。
            Element對象代表的是XML文檔中的標(biāo)簽元素,繼承于Node,亦是Node的最主要的子對象。在
            標(biāo)簽中可以包含有屬性,因而Element對象中有存取其屬性的方法,而任何Node中定義的方法,
            也可以用在Element對象上面。
            getElementsByTagName(String):返回一個(gè)NodeList對象,它包含了在這個(gè)標(biāo)簽中其下的子孫
            節(jié)點(diǎn)中具有給定標(biāo)簽名字的標(biāo)簽。
            getTagName():返回一個(gè)代表這個(gè)標(biāo)簽名字的字符串。
            getAttribute(String):返回標(biāo)簽中給定屬性名稱的屬性的值。在這兒需要主要的是,應(yīng)為XML
            文檔中允許有實(shí)體屬性出現(xiàn),而這個(gè)方法對這些實(shí)體屬性并不適用。這時(shí)候需要用到
            getAttributeNodes()方法來得到一個(gè)Attr對象來進(jìn)行進(jìn)一步的操作。
            getAttributeNode(String):返回一個(gè)代表給定屬性名稱的Attr對象。
            Attr對象代表了某個(gè)標(biāo)簽中的屬性。Attr繼承于Node,但是因?yàn)锳ttr實(shí)際上是包含在Element中
            的,它并不能被看作是Element的子對象,因而在DOM中Attr并不是DOM樹的一部分,所以Node
            中的getparentNode(),getpreviousSibling()和getnextSibling()返回的都將是null。也就是說,
            Attr其實(shí)是被看作包含它的Element對象的一部分,它并不作為DOM樹中單獨(dú)的一個(gè)節(jié)點(diǎn)出現(xiàn)。
            這一點(diǎn)在使用的時(shí)候要同其它的Node子對象相區(qū)別。
            需要說明的是,上面所說的DOM對象在DOM中都是用接口定義的,在定義的時(shí)候使用的是與
            具體語言無關(guān)的IDL語言來定義的。因而,DOM其實(shí)可以在任何面向?qū)ο蟮恼Z言中實(shí)現(xiàn),只要
            它實(shí)現(xiàn)了DOM所定義的接口和功能就可以了。同時(shí),有些方法在DOM中并沒有定義,是用IDL
            的屬性來表達(dá)的,當(dāng)被映射到具體的語言時(shí),這些屬性被映射為相應(yīng)的方法。
            有了上面的介紹,相信你對DOM理解的更多了吧。下面的例子將讓你對DOM更加熟悉起來。
            先說說這個(gè)例子到底要做的是什么吧,我們希望在一個(gè)名為link.xml文件中保存了一些URL地
            址,通過一個(gè)簡單的程序,我們可以通過DOM把這些URL讀出并顯示出來,也可以反過來向這
            個(gè)XML文件中寫入加入的URL地址。很簡單,卻很實(shí)用,也足夠來例示DOM的絕大部分用法了。
            XML文件本身不復(fù)雜,就不給出它的DTD了。link.xml:
            2.DOM實(shí)例
            <?xml version="1.0" standalone="yes"?>
            <links>
            <link>
            <text>JSP Insider</text>
            <url newWindow="no">http://www.jspinsider.com</url>
            <author>JSP Insider</author>
            <date>
            <day>2</day>
            <month>1</month>
            <year>2001</year>
            </date>
            <description>A JSP information site.</description>
            </link>
            <link>
            <text>The makers of Java</text>
            <url newWindow="no">http://java.sun.com</url>
            <author>Sun Microsystems</author>
            <date>
            <day>3</day>
            <month>1</month>
            <year>2001</year>
            </date>
            <description>Sun Microsystem's website.</description>
            </link>
            <link>
            第一個(gè)程序我們稱為xmldisplay.java,具體的程序清單可以在附件中找到。主要的功能就是讀
            取這個(gè)XML文件中各個(gè)節(jié)點(diǎn)的內(nèi)容,然后在格式化輸出在System.out上,我們來看看這個(gè)程序:
            這是引入必要的類, 因?yàn)樵谶@里使用的是Sun 所提供的XML 解析器, 因而需要引入
            java.xml.parsers包,其中包含了有DOM解析器和SAX解析器的具體實(shí)現(xiàn)。org.w3c.dom包中定
            義了w3c所制定的DOM接口。
            除了上面講到的,還有一個(gè)小技巧,對Document對象調(diào)用normalize(),可以去掉XML文檔中作
            為格式化內(nèi)容的空白而映射在DOM樹中的不必要的Text Node對象。否則你得到的DOM樹可能
            并不如你所想象的那樣。特別是在輸出的時(shí)候,這個(gè)normalize()更為有用。
            剛才說過,XML文檔中的空白符也會被作為對象映射在DOM樹中。因而,直接調(diào)用Node方法
            的getChildNodes方法有時(shí)候會有些問題,有時(shí)不能夠返回所期望的NodeList對象。解決的辦法
            是使用Element的getElementByTagName(String),返回的NodeLise就是所期待的對象了。然
            后,可以用item()方法提取想要的元素。
            <text>The standard JSP container</text>
            <url newWindow="no">http://jakarta.apache.org</url>
            <author>Apache Group</author>
            <date>
            <day>4</day>
            <month>1</month>
            <year>2001</year>
            </date>
            <description>Some great software.</description>
            </link>
            </links>
            import javax.xml.parsers.*;
            import org.w3c.dom.*;
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder=factory.newDocumentBuilder();
            Document doc=builder.parse("links.xml");
            doc.normalize();
            NodeList links =doc.getElementsByTagName("link");
            for (int i=0;i<links.getLength();i++){
            Element link=(Element) links.item(i);
            System.out.print("Content: ");
            System.out.println(link.getElementsByTagName("text").item(0).getFirstChild().getNodeValue()
            上面的代碼片斷就完成了對XML文檔內(nèi)容的格式化輸出。只要注意到一些細(xì)節(jié)的問題,比如
            getFirstChile()方法和getElementsByTagName()方法的使用,這些還是比較容易的。
            下面的內(nèi)容,就是在修改了DOM樹后重新寫入到XML文檔中去的問題了。這個(gè)程序名為
            xmlwrite.java。在JAXP1.0版本中,并沒有直接的類和方法能夠處理XML文檔的寫入問題,需
            要借助其它包中的一些輔助類。而在JAXP1.1版本中,引入了對XSLT的支持,所謂XSLT,就
            是對XML文檔進(jìn)行變換(Translation)后,得到一個(gè)新的文檔結(jié)構(gòu)。利用這個(gè)新加入的功能,
            我們就能夠很方便的把新生成或者修改后的DOM樹從新寫回到XML文件中去了,下面我們來看
            看代碼的實(shí)現(xiàn),這段代碼的主要功能是向links.xml文件中加入一個(gè)新的link節(jié)點(diǎn):
            新引入的java.xml.transform包中的幾個(gè)類,就是用來處理XSLT變換的。
            我們希望在上面的XML文件中加入一個(gè)新的link節(jié)點(diǎn),因而首先還是要讀入links.xml文件,構(gòu)建
            一個(gè)DOM樹,然后再對這個(gè)DOM樹進(jìn)行修改(添加節(jié)點(diǎn)),最后把修改后的DOM寫回到links.xml
            文件中:
            );
            System.out.print("URL: ");
            System.out.println(link.getElementsByTagName("url").item(0).getFirstChild().getNodeValue());
            System.out.print("Author: ");
            System.out.println(link.getElementsByTagName("author").item(0).getFirstChild().getNodeVal
            ue());
            System.out.print("Date: ");
            Element linkdate=(Element) link.getElementsByTagName("date").item(0);
            String day=linkdate.getElementsByTagName("day").item(0).getFirstChild().getNodeValue();
            String
            month=linkdate.getElementsByTagName("month").item(0).getFirstChild().getNodeValue();
            String year=linkdate.getElementsByTagName("year").item(0).getFirstChild().getNodeValue();
            System.out.println(day+"-"+month+"-"+year);
            System.out.print("Description: ");
            System.out.println(link.getElementsByTagName("description").item(0).getFirstChild().getNod
            eValue());
            System.out.println();
            }
            import javax.xml.parsers.*;
            import javax.xml.transform.*;
            import javax.xml.transform.dom.DOMSource;
            import javax.xml.transform.stream.StreamResult;
            import org.w3c.dom.*;
            為了看清重點(diǎn),簡化程序,我們把要加入的內(nèi)容硬編碼到記憶String對象中,而實(shí)際操作中,往
            往利用一個(gè)界面來提取用戶輸入,或者通過JDBC從數(shù)據(jù)庫中提取想要的內(nèi)容。
            首先應(yīng)該明了的是,無論什么類型的Node,Text型的也好,Attr型的也好,Element型的也好,
            它們的創(chuàng)建都是通過Document對象中的createXXX()方法來創(chuàng)建的(XXX代表具體要?jiǎng)?chuàng)建的類
            型),因此,我們要向XML文檔中添加一個(gè)link項(xiàng)目,首先要?jiǎng)?chuàng)建一個(gè)link對象:
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder=factory.newDocumentBuilder();
            Document doc=builder.parse("links.xml");
            doc.normalize();
            //---取得變量----
            String text="Hanzhong's Homepage";
            String url="String author="Hzliu Liu";
            String discription="A site from Hanzhong Liu, give u lots of suprise!!!";
            Text textseg;
            Element link=doc.createElement("link");
            Element linktext=doc.createElement("text");
            textseg=doc.createTextNode(text);
            linktext.appendChild(textseg);
            link.appendChild(linktext);
            Element linkurl=doc.createElement("url");
            textseg=doc.createTextNode(url);
            linkurl.appendChild(textseg);
            link.appendChild(linkurl);
            Element linkauthor=doc.createElement("author");
            textseg=doc.createTextNode(author);
            linkauthor.appendChild(textseg);
            link.appendChild(linkauthor);
            java.util.Calendar rightNow = java.util.Calendar.getInstance();
            String day=Integer.toString(rightNow.get(java.util.Calendar.DAY_OF_MONTH));
            String month=Integer.toString(rightNow.get(java.util.Calendar.MONTH));
            String year=Integer.toString(rightNow.get(java.util.Calendar.YEAR));
            Element linkdate=doc.createElement("date");
            Element linkdateday=doc.createElement("day");
            textseg=doc.createTextNode(day);
            linkdateday.appendChild(textseg);
            Element linkdatemonth=doc.createElement("month");
            創(chuàng)建節(jié)點(diǎn)的過程可能有些千篇一律,但需要注意的地方是,對Element中所包含的text(在DOM
            中,這些text也是代表了一個(gè)Node的,因此也必須為它們創(chuàng)建相應(yīng)的node),不能直接用Element
            對象的setNodeValue()方法來設(shè)置這些text的內(nèi)容,而需要用創(chuàng)建的Text對象的setNodeValue()
            方法來設(shè)置文本,這樣才能夠把創(chuàng)建的Element和其文本內(nèi)容添加到DOM樹中。看看前面的代
            碼,你會更好的理解這一點(diǎn):
            最后,不要忘記把創(chuàng)建好的節(jié)點(diǎn)添加到DOM樹中。Document類的getDocumentElement()方法,
            返回代表文檔根節(jié)點(diǎn)的Element對象。在XML文檔中,根節(jié)點(diǎn)一定是唯一的。
            然后就是用XSLT把DOM樹輸出了。這里的TransformerFactory也同樣應(yīng)用了工廠模式,使得具
            體的代碼同具體的變換器無關(guān)。實(shí)現(xiàn)的方法和DocumentBuilderFactory相同,這兒就不贅述了。
            Transformer類的transfrom方法接受兩個(gè)參數(shù)、一個(gè)數(shù)據(jù)源Source和一個(gè)輸出目標(biāo)Result。這里
            分別使用的是DOMSource和StreamResult,這樣就能夠把DOM的內(nèi)容輸出到一個(gè)輸出流中,
            當(dāng)這個(gè)輸出流是一個(gè)文件的時(shí)候,DOM的內(nèi)容就被寫入到文件中去了。
            好了,關(guān)于DOM的話題就先到這里,下篇文章將介紹的內(nèi)容是SAX。請看Java與XML讀寫之
            SAX篇
            textseg=doc.createTextNode(month);
            linkdatemonth.appendChild(textseg);
            Element linkdateyear=doc.createElement("year");
            textseg=doc.createTextNode(year);
            linkdateyear.appendChild(textseg);
            linkdate.appendChild(linkdateday);
            linkdate.appendChild(linkdatemonth);
            linkdate.appendChild(linkdateyear);
            link.appendChild(linkdate);
            Element linkdiscription=doc.createElement("description");
            textseg=doc.createTextNode(discription);
            linkdiscription.appendChild(textseg);
            link.appendChild(linkdiscription);
            doc.getDocumentElement().appendChild(link);
            TransformerFactory tFactory =TransformerFactory.newInstance();
            Transformer transformer = tFactory.newTransformer();
            DOMSource source = new DOMSource(doc);
            StreamResult result = new StreamResult(new java.io.File("links.xml"));
            transformer.transform(source, result);

            FeedBack:
            # re: 【轉(zhuǎn)】Java與XML讀寫之DOM篇 2008-01-08 14:50 java綜合網(wǎng)
            http://www.javazh.cn

            不錯(cuò),不錯(cuò)~~~  回復(fù)  更多評論
              
            老司机国内精品久久久久| 国内精品久久久久久野外| 久久这里有精品视频| 无夜精品久久久久久| 日产精品久久久一区二区| 久久美女人爽女人爽| 久久人做人爽一区二区三区| 精品无码久久久久国产| 久久成人国产精品一区二区| 久久久久人妻一区精品色| 久久精品这里只有精99品| 久久久久成人精品无码中文字幕 | 国产美女久久精品香蕉69| 久久久久国产精品三级网| 国产精品无码久久久久久| 伊人情人综合成人久久网小说| 久久亚洲国产午夜精品理论片| 亚洲国产视频久久| 狠狠精品干练久久久无码中文字幕 | 中文字幕久久精品| 亚洲天堂久久精品| 久久精品午夜一区二区福利| 99精品久久久久久久婷婷| 国产精品免费久久| 久久久久久久尹人综合网亚洲| 亚洲国产另类久久久精品| yy6080久久| 婷婷久久五月天| 久久免费视频1| 91久久九九无码成人网站| 免费观看成人久久网免费观看| 精品熟女少妇av免费久久| 97久久久精品综合88久久| 粉嫩小泬无遮挡久久久久久| 狠狠88综合久久久久综合网 | 久久国产精品波多野结衣AV| 久久九九青青国产精品| 久久国产精品波多野结衣AV| 尹人香蕉久久99天天拍| 亚洲日本va中文字幕久久| 久久亚洲精精品中文字幕|