簡體   English   中英

Java:XML Parser

[英]Java:XML Parser

我有一個像這樣的響應XML -

<Response> <aa> <Fromhere> <a1>Content</a1> <a2>Content</a2> </Fromhere> </aa> </Response>

我想在字符串中從<Fromhere>提取整個內容到</Fromhere> 是否可以通過任何字符串函數或通過XML解析器執行此操作?

請指教。

您可以嘗試使用XPath方法來簡化XML解析:

InputStream response = new ByteArrayInputStream("<Response> <aa> "
        + "<Fromhere> <a1>Content</a1> <a2>Content</a2> </Fromhere> "
        + "</aa> </Response>".getBytes()); /* Or whatever. */

DocumentBuilder builder = DocumentBuilderFactory
        .newInstance().newDocumentBuilder();
Document doc = builder.parse(response);

XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile("string(/Response/aa/FromHere)");
String result = (String)expr.evaluate(doc, XPathConstants.STRING);

請注意,我還沒有嘗試過這段代碼。 它可能需要調整。

通過XML解析器。 使用字符串函數來解析XML是一個壞主意......
除了上面提到的Sun教程之外,你可以查看關於Java和XML的DZone Refcardz ,我發現它是一個很好的,簡潔的解釋如何做到這一點。
但是,關於該主題可能有大量的Web資源,包括在這個網站上。

您可以應用XSLT樣式表來提取所需的內容。

此樣式表應該適合您的示例:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/Response/aa/Fromhere/*">
        <xsl:copy>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

使用以下內容應用它(不包括異常處理):

String xml = "<Response> <aa> <Fromhere> <a1>Content</a1> <a2>Content</a2> </Fromhere> </aa> </Response>";
Source xsl = new StreamSource(new FileReader("/path/to/file.xsl");

TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer(xsl);
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

StringWriter out = new StringWriter();
transformer.transform(new StreamSource(new StringReader(xml)), new StreamResult(out));

System.out.println(out.toString());

這適用於從1.4開始的任何Java版本。

這應該工作

import java.util.regex.*

Pattern p = Pattern.compile("<Fromhere>.*</Fromhere>");
Matcher m = p.matcher(responseString);
String whatYouWant = m.group();

使用Scanner會更加冗長,但這也可能有用。

對於比我更有經驗的人來說這是否是一個好主意。

一種選擇是使用StreamFilter

class MyFilter implements StreamFilter {
  private boolean on;

  @Override
  public boolean accept(XMLStreamReader reader) {
    final String element = "Fromhere";
    if (reader.isStartElement() && element.equals(reader.getLocalName())) {
      on = true;
    } else if (reader.isEndElement()
        && element.equals(reader.getLocalName())) {
      on = false;
      return true;
    }
    return on;
  }
}

結合Transformer ,您可以使用它來安全地解析邏輯等效的標記,如下所示:

<Response>
  <!-- <Fromhere></Fromhere> -->
  <aa>
    <Fromhere>
      <a1>Content</a1> <a2>Content</a2>
    </Fromhere>
  </aa>
</Response>

演示:

StringWriter writer = new StringWriter();

XMLInputFactory inputFactory = XMLInputFactory.newInstance();
XMLStreamReader reader = inputFactory
    .createXMLStreamReader(new StringReader(xmlString));
reader = inputFactory.createFilteredReader(reader, new MyFilter());
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.transform(new StAXSource(reader), new StreamResult(writer));

System.out.println(writer.toString());

這是Massimiliano Fliri方法的程序化變體。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM