詳解Java中的XML解析

詳解Java中的XML解析

前言

XML,全稱Extensibible Markup Language, 主要用于數(shù)據(jù)的保存或者文件傳輸,其主要特性如下所示:

  • 以標(biāo)簽為主的標(biāo)記語(yǔ)言
  • 支持自定義標(biāo)簽,支持自我解釋
  • 與具體技術(shù)無(wú)關(guān)
  • 支持驗(yàn)證
  • 方便人類的讀寫(xiě)

XML示例

為了更好的了解XML,下面我們提供一個(gè)簡(jiǎn)單的XML文件,內(nèi)容如下所示:

<?xml version="1.0" encoding="UTF-8" ?>

<!--
    根元素為students
    注意XML文件中有且僅有一個(gè)根元素
-->
<students>
    <!--
        子元素student
        id屬性同樣可以作為student的子元素
        為了演示方便爱谁,這里將其作為屬性
    -->
    <student id="123">
        <!--
            student有三個(gè)子元素
            name、age、gender
         -->
        <name>xuhuanfeng</name>
        <age>22</age>
        <gender>male</gender>
    </student>
    <!--同上-->
    <student id="456">
        <name>Tom</name>
        <age>23</age>
        <gender>femal</gender>
    </student>
    <!--同上-->
    <student id="789">
        <name>Lily</name>
        <age>24</age>
        <gender>femal</gender>
    </student>
</students>

在XML中每個(gè)元素都可以有子元素/值锯七,元素可以有屬性,具體關(guān)于XML的內(nèi)容還請(qǐng)查看官方的文檔誉己,接下來(lái)的內(nèi)容主要為Java對(duì)XML文件的解析眉尸。

XML解析

XML解析主要有兩種方式,一種稱為DOM解析巫延,另外一種稱之為SAX解析效五。

  • DOM解析:Document Object Model,簡(jiǎn)單的來(lái)講炉峰,DOM解析就是讀取XML文件畏妖,然后在文件文檔描述的內(nèi)容在內(nèi)存中生成整個(gè)文檔樹(shù)。
  • SAX解析:Simple API for XML疼阔,簡(jiǎn)單的來(lái)講戒劫,SAX是基于事件驅(qū)動(dòng)的流式解析模式半夷,一邊去讀文件,一邊解析文件迅细,在解析的過(guò)程并不保存具體的文件內(nèi)容巫橄。

兩種解析方式各有千秋,也都有各自的有點(diǎn)和缺點(diǎn)茵典,這里簡(jiǎn)單羅列如下:

  • DOM解析:

    • 優(yōu)點(diǎn):在內(nèi)存中形成了整個(gè)文檔樹(shù)湘换,有了文檔樹(shù),就可以隨便對(duì)文檔中任意的節(jié)點(diǎn)進(jìn)行操作(增加節(jié)點(diǎn)统阿、刪除節(jié)點(diǎn)彩倚、修改節(jié)點(diǎn)信息等),而且由于已經(jīng)有了整個(gè)的文檔樹(shù)扶平,可以實(shí)現(xiàn)對(duì)任意節(jié)點(diǎn)的隨機(jī)訪問(wèn)帆离。
    • 缺點(diǎn):由于需要在內(nèi)存中形成文檔樹(shù),需要消耗的內(nèi)存比較大结澄,尤其是當(dāng)文件比較大的時(shí)候哥谷,消耗的代價(jià)還是不容小視的。
  • SAX解析:

    • 優(yōu)點(diǎn):SAX解析由于是一邊讀取文檔一邊解析的麻献,所以所占用的內(nèi)存相對(duì)來(lái)說(shuō)比較小们妥。
    • 缺點(diǎn):無(wú)法保存文檔的信息,無(wú)法實(shí)現(xiàn)隨機(jī)訪問(wèn)節(jié)點(diǎn)勉吻,當(dāng)文檔需要編輯的時(shí)候蒜危,使用SAX解析就比較麻煩了要糊。

    對(duì)XML的兩種不同解析機(jī)制有一定的了解之后祭隔,接下來(lái)我們就來(lái)具體的看下德频,在Java中是如何解析的。

    DOM解析

    關(guān)于DOM的解析源譬,這里就不再做過(guò)多的解釋了集惋,直接通過(guò)代碼來(lái)查看具體的操作過(guò)程

解析文檔

public void parse() {
      // students的內(nèi)容為上面所示XML代碼內(nèi)容
      File file = new File("D:/students.xml");

      try {
          // 創(chuàng)建文檔解析的對(duì)象
          DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
          DocumentBuilder builder = factory.newDocumentBuilder();

          // 解析文檔,形成文檔樹(shù)踩娘,也就是生成Document對(duì)象
          Document document = builder.parse(file);

          // 獲得根節(jié)點(diǎn)
          Element rootElement = document.getDocumentElement();
          System.out.printf("Root Element: %s\n", rootElement.getNodeName());

          // 獲得根節(jié)點(diǎn)下的所有子節(jié)點(diǎn)
          NodeList students = rootElement.getChildNodes();
          for (int i = 0; i < students.getLength(); i++){
              // 獲得第i個(gè)子節(jié)點(diǎn)
              Node childNode = students.item(i);
              // 由于節(jié)點(diǎn)多種類型刮刑,而一般我們需要處理的是元素節(jié)點(diǎn)
              // 元素節(jié)點(diǎn)就是非空的子節(jié)點(diǎn),也就是還有孩子的子節(jié)點(diǎn)
              if (childNode.getNodeType() == Node.ELEMENT_NODE){
                  Element childElement = (Element)childNode;
                  System.out.printf(" Element: %s\n", childElement.getNodeName());
                  System.out.printf("  Attribute: id = %s\n", childElement.getAttribute("id"));
                  // 獲得第二級(jí)子元素
                  NodeList childNodes = childElement.getChildNodes();
                  for (int j = 0; j < childNodes.getLength(); j++){
                      Node child = childNodes.item(j);
                      if (child.getNodeType() == Node.ELEMENT_NODE){
                          Element eChild = (Element) child;
                          System.out.printf("  sub Element: %s value= %s\n", eChild.getNodeName(), eChild.getTextContent());
                      }
                  }
              }
          }
      } catch (ParserConfigurationException e) {
          e.printStackTrace();
      } catch (SAXException e) {
          e.printStackTrace();
      } catch (IOException e) {
          e.printStackTrace();
      }
  }

解析的結(jié)果如下所示:

Root Element: students
Element: student
Attribute: id = 123
sub Element: name value= xuhuanfeng
sub Element: age value= 22
sub Element: gender value= male
# 其余兩個(gè)student節(jié)點(diǎn)由于篇幅原因這里省略...

當(dāng)我們需要特定的節(jié)點(diǎn)的數(shù)據(jù)的時(shí)候养渴,可以根據(jù)具體的數(shù)據(jù)從上面的解析過(guò)程中進(jìn)行數(shù)據(jù)的篩選即可雷绢,所以這里不演示如果進(jìn)行數(shù)據(jù)的選取了(畢竟整個(gè)文檔的內(nèi)容都讀取出來(lái)了:))

編輯文檔

由于DOM解析是直接在內(nèi)存中生成對(duì)應(yīng)的文檔樹(shù),所以我們可以很方便地對(duì)其進(jìn)行編輯理卑,這里演示修改id = 123的子元素name的值為Huanfeng.Xu翘紊,具體代碼如下所示:

public void modify(){
    try {
        // 生成文檔樹(shù)的過(guò)程同前面所示,這里不進(jìn)行過(guò)多的解釋
        File file = new File("d:/students.xml");
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();

        Document document = builder.parse(file);

        Element rootElement = document.getDocumentElement();
        NodeList students = rootElement.getChildNodes();
        for (int i = 0; i < students.getLength(); i++){
            Node tmp = students.item(i);
            if (tmp.getNodeType() == Node.ELEMENT_NODE){
                Element element = (Element)tmp;
                // 獲得id為123的student節(jié)點(diǎn)
                String attr = element.getAttribute("id");
                if ("123".equalsIgnoreCase(attr)){
                    NodeList childNodes = element.getChildNodes();
                    for (int j = 0; j < childNodes.getLength(); j++){
                        Node childNode = childNodes.item(j);
                        if (childNode.getNodeType() == Node.ELEMENT_NODE) {
                            Element childElement = (Element) childNode;
                            // 修改子節(jié)點(diǎn)name的值
                            if (childElement.getNodeName().equalsIgnoreCase("name")) {
                                childElement.setTextContent("Huanfeng.Xu");
                                break;
                            }
                        }
                    }
                }
            }
        }

        // 獲得Transformer對(duì)象藐唠,用于輸出文檔
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        // 封裝成DOMResource對(duì)象
        DOMSource domSource = new DOMSource(document);
        Result result = new StreamResult("d:/newStudents.xml");
        // 輸出結(jié)果
        transformer.transform(domSource, result);

    } catch (ParserConfigurationException e) {
        e.printStackTrace();
    } catch (SAXException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (TransformerConfigurationException e) {
        e.printStackTrace();
    } catch (TransformerException e) {
        e.printStackTrace();
    }
}

可以看到帆疟,基本的操作跟解析文檔是一致的鹉究,這也非常好理解,修改嘛踪宠,肯定先要解析文檔然后獲得需要修改的節(jié)點(diǎn)信息自赔,這里同樣可以對(duì)節(jié)點(diǎn)進(jìn)行刪除、增加操作柳琢,原理同上绍妨,這里就不進(jìn)行演示。

SAX解析

關(guān)于SAX解析的原理柬脸,這里就不再做過(guò)多的解釋痘绎,同上面DOM的解析一樣,這里我們直接通過(guò)代碼來(lái)查看具體的操作過(guò)程

解析文檔

/**
 *  由于SAX解析是基于事件機(jī)制的肖粮,也就是當(dāng)遇到指定元素的時(shí)候,解析器就會(huì)自動(dòng)調(diào)用
 *  回調(diào)函數(shù)尔苦,所以使用SAX解析的時(shí)候涩馆,需要?jiǎng)?chuàng)建自定義的Handler并且繼承自DefaultHandler
 *  并且將其傳給解析器,用于指定需要進(jìn)行回調(diào)的內(nèi)容
 */
class SAXHandler extends DefaultHandler{

    /**
     * 用于標(biāo)志是否已經(jīng)讀取到指定的元素
     */
    private boolean isName;
    private boolean isAge;
    private boolean isGender;

    @Override
    public void startDocument() throws SAXException {
        System.out.println("Starting parse the document");
    }

    @Override
    public void endDocument() throws SAXException {
        System.out.println("Ending parse the document");
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        if ("student".equalsIgnoreCase(qName)){
            System.out.println("student");
        }else if ("name".equalsIgnoreCase(qName)){
            isName = true;
        }else if ("age".equalsIgnoreCase(qName)){
            isAge = true;
        }else if ("gender".equalsIgnoreCase(qName)){
            isGender = true;
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        String content = new String(ch, start, length);
        if (isName){
            System.out.printf("  Name: %s\n", content);
            isName = false; // 這里需要額外注意允坚,當(dāng)讀取到一個(gè)節(jié)點(diǎn)之后魂那,需要
                              // 把該節(jié)點(diǎn)的標(biāo)志去除,不然下一次讀取會(huì)出現(xiàn)問(wèn)題
        }else if (isAge){
            System.out.printf("  Age: %s\n", content);
            isAge = false;
        }else if (isGender){
            System.out.printf("  Gender: %s\n", content);
            isGender = false;
        }
    }
}

public void parser(){
    try {
        File file = new File("d:/students.xml");
        // 創(chuàng)建一個(gè)SAX解析器
        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
        javax.xml.parsers.SAXParser parser = saxParserFactory.newSAXParser();
        // 解析對(duì)應(yīng)的文件
        parser.parse(file, new SAXHandler());
    } catch (ParserConfigurationException e) {
        e.printStackTrace();
    } catch (SAXException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

對(duì)應(yīng)的輸出結(jié)果如下所示:

student
Name: xuhuanfeng
Age: 22
Gender: male
# 這里由于篇幅原因稠项,省略其他兩個(gè)輸出內(nèi)容

由于SAX解析本身不利于節(jié)點(diǎn)的保存以及編輯涯雅,所以這里就不演示器編輯的過(guò)程。

第三方類庫(kù)解析

上面的內(nèi)容就是XML解析的最基本的操作了展运,不過(guò)活逆,由于原生API操作不方便,加上效率不怎么高拗胜,所以就出現(xiàn)了許多的第三方的解析類庫(kù)蔗候,最常使用的包括了JDOM、StAX埂软、XPath锈遥、DOM4j等,下面我們將逐個(gè)演示其操作

JDOM解析

JDOM是我們所要接觸的第一個(gè)第三方解析類庫(kù)勘畔,其操作的原理是基于DOM解析操作所灸,不過(guò)JDOM的解析效率比原生操作高,內(nèi)存占用相對(duì)低炫七,使用的時(shí)候需要導(dǎo)入JDOM的jar文件爬立,下載地址

解析文檔

public void parse(){
    try {
        File file = new File("d:/students.xml");
        // 獲得一個(gè)解析器
        SAXBuilder saxBuilder = new SAXBuilder();
        Document document = saxBuilder.build(file);
        // 獲得根元素
        Element rootElement = document.getRootElement();
        System.out.printf("Root Element %s\n", rootElement.getName());
        List<Element> elements = rootElement.getChildren();
        for (Element e : elements){
            System.out.printf(" %s\n", e.getName());
            System.out.printf("  Name: %s\n", e.getChild("name").getTextTrim());
            System.out.printf("  Age: %s\n", e.getChild("age").getTextTrim());
            System.out.printf("  Gender: %s\n", e.getChild("gender").getTextTrim());
        }
    } catch (JDOMException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

可以看到使用JDOM進(jìn)行解析是比較方便的,而且由于JDOM使用了List等容器類万哪,更加方便操作了懦尝。

StAX解析

StAx是我們要使用的第二個(gè)第三方解析類庫(kù)知纷,StAX的實(shí)現(xiàn)原理為SAX操作,不過(guò)StAX提供了比原生SAX解析更加方便的操作陵霉,使用時(shí)同樣需要導(dǎo)入其jar文件琅轧,下載地址

解析文檔

public void parse(){

    boolean isName = false;
    boolean isAge = false;
    boolean isGender = false;

    try {
        File file = new File("d:/students.xml");
        // 獲得解析器
        XMLInputFactory factory = XMLInputFactory.newFactory();
        XMLEventReader reader = factory.createXMLEventReader(new FileReader(file));

        while (reader.hasNext()){
            // 獲得事件
            XMLEvent event = reader.nextEvent();
            switch (event.getEventType()){
                // 解析事件的類型
                case XMLStreamConstants.START_ELEMENT:
                    StartElement startElement = event.asStartElement();
                    String qName = startElement.getName().getLocalPart();
                    if ("name".equalsIgnoreCase(qName)){
                        isName = true;
                    }else if ("age".equalsIgnoreCase(qName)){
                        isAge = true;
                    }else if ("gender".equalsIgnoreCase(qName)){
                        isGender = true;
                    }
                    break;
                case XMLStreamConstants.CHARACTERS:
                    Characters characters = event.asCharacters();
                    if (isName){
                        System.out.printf(" Name: %s\n", characters.getData());
                        isName = false;
                    }else if (isAge){
                        System.out.printf(" Age: %s\n", characters.getData());
                        isAge = false;
                    }else if (isGender){
                        System.out.printf(" Gender: %s\n", characters.getData());
                        isGender = false;
                    }
                    break;
            }
        }
    } catch (XMLStreamException e) {
        e.printStackTrace();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
}

XPath

XPath從嚴(yán)格意義上來(lái)講并不是一種解析方式,不過(guò)XPath提供了一種定位節(jié)點(diǎn)的方式踊挠,XPath表達(dá)式乍桂,通過(guò)該表達(dá)式,我們可以定位到指定特性的一個(gè)或者一組節(jié)點(diǎn)

常用的XPath表達(dá)式如下所示:

/ :從根節(jié)點(diǎn)開(kāi)始查找

//:從當(dāng)前節(jié)點(diǎn)開(kāi)始查找

. :選擇當(dāng)前節(jié)點(diǎn)

..:選擇當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)

@:指定元素

還有其他一些表達(dá)式效床,可以參考XPath表達(dá)式

解析文檔

public void parse(){
     try {
         File file = new File("d:/students.xml");
         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
         DocumentBuilder builder = factory.newDocumentBuilder();
         // 創(chuàng)建xpath對(duì)象
         XPath xPath = XPathFactory.newInstance().newXPath();
         Document document = builder.parse(file);
         // 編寫(xiě)xpath表達(dá)式
         String expression = "/students/student";
         NodeList students = (NodeList)xPath.compile(expression).evaluate(document, XPathConstants.NODESET);
         for (int i = 0; i < students.getLength(); i++){
             Node node = students.item(i);
             if (node.getNodeType() == Node.ELEMENT_NODE){
                 Element element = (Element) node;
                 System.out.printf(" Element: %s\n", element.getNodeName());
                 System.out.printf(" Name: %s\n", element.getElementsByTagName("name").item(0).getTextContent());
                 System.out.printf(" Age: %s\n", element.getElementsByTagName("age").item(0).getTextContent());
                 System.out.printf(" Gender: %s\n", element.getElementsByTagName("gender").item(0).getTextContent());
             }
         }
     } catch (ParserConfigurationException e) {
         e.printStackTrace();
     } catch (SAXException e) {
         e.printStackTrace();
     } catch (IOException e) {
         e.printStackTrace();
     } catch (XPathExpressionException e) {
         e.printStackTrace();
     }
 }

可以看到睹酌,使用XPath技術(shù)本質(zhì)上還是使用DOM解析,只不過(guò)借助XPath表達(dá)式剩檀,可以很方便地定位到指定元素

DOM4J解析

DOM4J是一個(gè)比較優(yōu)秀的解析類庫(kù)憋沿,也是目前使用得比較多的庫(kù)類,使用的時(shí)候可以配合XPath技術(shù)來(lái)輔助定位某一個(gè)節(jié)點(diǎn)沪猴,使用的時(shí)候需要導(dǎo)入對(duì)應(yīng)的jar文件辐啄,下載地址,注意使用DOM4J的時(shí)候需要導(dǎo)入兩個(gè)jar文件运嗜,DOM4J本身的jar文件以及jaxen文件

解析文檔

public void parse() throws DocumentException {
       File file = new File("d:/students.xml");

       // 加載文檔
       SAXReader reader = new SAXReader();
       Document document = reader.read(file);

       Element rootElement = document.getRootElement();
       System.out.printf("Root Element: %s\n", rootElement.getName());
       // 使用XPath表達(dá)式來(lái)定位節(jié)點(diǎn)
       List<Node> students = document.selectNodes("/students/student");
       for (Node n: students){
           System.out.printf("Element: %s\n", n.getName());

           System.out.printf("Name: %s\n", n.selectSingleNode("name").getText());
           System.out.printf("Age: %s\n", n.selectSingleNode("age").getText());
           System.out.printf("Gender: %s\n", n.selectSingleNode("gender").getText());
       }
   }

可以看到壶辜,使用DOM4J解析文檔是非常方便的,不僅如此担租,使用DOM4J生成文檔也是非常方便的

生成文檔

public void create() throws IOException {
    Document document = DocumentHelper.createDocument();
    Element root = document.addElement("students");

    Element student = root.addElement("student");

    student.addElement("name")
            .addText("xuhuanfeng");

    student.addElement("age")
            .addText("22");

    OutputFormat format = OutputFormat.createPrettyPrint();
    XMLWriter writer = new XMLWriter(System.out);
    writer.write(document);
}

總結(jié)

本節(jié)我們學(xué)習(xí)了XML解析的機(jī)制砸民,包括了DOM解析以及SAX解析,并且通過(guò)具體實(shí)例使用不同解析技術(shù)進(jìn)行解析奋救,還了解了幾個(gè)常用的XML解析類庫(kù)岭参,包括了JDOM、StAX尝艘、XPath冗荸、DOM4J等,并且通過(guò)具體操作更加具體地了解了其操作的過(guò)程利耍。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蚌本,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子隘梨,更是在濱河造成了極大的恐慌程癌,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件轴猎,死亡現(xiàn)場(chǎng)離奇詭異嵌莉,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)捻脖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門锐峭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)中鼠,“玉大人,你說(shuō)我怎么就攤上這事沿癞≡停” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,435評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵椎扬,是天一觀的道長(zhǎng)惫搏。 經(jīng)常有香客問(wèn)我,道長(zhǎng)蚕涤,這世上最難降的妖魔是什么筐赔? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,509評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮揖铜,結(jié)果婚禮上茴丰,老公的妹妹穿的比我還像新娘。我一直安慰自己天吓,他們只是感情好贿肩,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,611評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著失仁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪们何。 梳的紋絲不亂的頭發(fā)上萄焦,一...
    開(kāi)封第一講書(shū)人閱讀 49,837評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音冤竹,去河邊找鬼拂封。 笑死,一個(gè)胖子當(dāng)著我的面吹牛鹦蠕,可吹牛的內(nèi)容都是我干的冒签。 我是一名探鬼主播,決...
    沈念sama閱讀 38,987評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼钟病,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼萧恕!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起肠阱,我...
    開(kāi)封第一講書(shū)人閱讀 37,730評(píng)論 0 267
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤票唆,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后屹徘,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體走趋,經(jīng)...
    沈念sama閱讀 44,194評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,525評(píng)論 2 327
  • 正文 我和宋清朗相戀三年噪伊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了簿煌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片氮唯。...
    茶點(diǎn)故事閱讀 38,664評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖姨伟,靈堂內(nèi)的尸體忽然破棺而出惩琉,到底是詐尸還是另有隱情,我是刑警寧澤授滓,帶...
    沈念sama閱讀 34,334評(píng)論 4 330
  • 正文 年R本政府宣布琳水,位于F島的核電站,受9級(jí)特大地震影響般堆,放射性物質(zhì)發(fā)生泄漏在孝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,944評(píng)論 3 313
  • 文/蒙蒙 一淮摔、第九天 我趴在偏房一處隱蔽的房頂上張望私沮。 院中可真熱鬧,春花似錦和橙、人聲如沸仔燕。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,764評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)晰搀。三九已至,卻和暖如春办斑,著一層夾襖步出監(jiān)牢的瞬間外恕,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,997評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工乡翅, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鳞疲,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,389評(píng)論 2 360
  • 正文 我出身青樓蠕蚜,卻偏偏與公主長(zhǎng)得像尚洽,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子靶累,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,554評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容