【问题标题】:Extract content between XML tags提取 XML 标记之间的内容
【发布时间】:2018-10-09 11:38:08
【问题描述】:

我有这个 XML 文件:

<ApiHeader>
    <OperationName>findEntitiesResponse</OperationName>
</ApiHeader>
<ResponseHeader>
    <CompletedSuccessfully>true</CompletedSuccessfully>
</ResponseHeader>
<Page>
    <StartAtRow>0</StartAtRow>
    <MaxRows>999999</MaxRows>
    <TotalRowCount>44</TotalRowCount>
</Page>
<Entity>
    <Carrier>xd
        <Id>11460</Id>
        <CarrierCode>11460</CarrierCode>
        <CarrierDescription>11460 LOGIS COUTTER</CarrierDescription>
        <LanguageCode>en</LanguageCode>
        <LanguageCodeDescr>Inglés</LanguageCodeDescr>
        <CarrierTypeCode>GENERAL</CarrierTypeCode>
        <CarrierTypeCodeDescr>GENERAL</CarrierTypeCodeDescr>
        <SCACCode>Default</SCACCode>
        </Memo>
    </Carrier>
</Entity>
<Entity>

有很多&lt;Entitiy&gt;CONTENT&lt;/Entity&gt;就像示例中的那个,但我保持简单。

我要做的是提取&lt;Entity&gt;&lt;/Entity&gt; 标记之间的所有内容。 我做了很多研究,但我发现最接近的是从 just one 标签中提取内容。

结果会是这样的

<Entity>
    <Carrier>xd
        <Id>11460</Id>
        <CarrierCode>11460</CarrierCode>
        <CarrierDescription>11460 LOGIS COUTTER</CarrierDescription>
        <LanguageCode>en</LanguageCode>
        <LanguageCodeDescr>Inglés</LanguageCodeDescr>
        <CarrierTypeCode>GENERAL</CarrierTypeCode>
        <CarrierTypeCodeDescr>GENERAL</CarrierTypeCodeDescr>
        <SCACCode>Default</SCACCode>
        </Memo>
    </Carrier>
</Entity>

请记住,可能有一个或多个&lt;Entity&gt;&lt;/Entity&gt; 标签。

非常感谢。

编辑

`公共类 ReadXMLFile { 私有最终静态字符串文件路径="C:\Users\AGOJSO\Desktop\jordi\test.xml";

public static void main(String[] args) {
    printXml();
}
public static void printXml() {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    try (InputStream in = new FileInputStream(filepath)) {
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.parse(in);
        NodeList list = filterNodesByXPath(doc, "//root/Entity");
        for (int i = 0; i < list.getLength(); i++) {
            Node node = list.item(i);
            printNode(node);
        }
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

private static NodeList filterNodesByXPath(Document doc, String xpathExpr) {
    try {
        XPathFactory xPathFactory = XPathFactory.newInstance();
        XPath xpath = xPathFactory.newXPath();
        XPathExpression expr = xpath.compile(xpathExpr);
        Object eval = expr.evaluate(doc, XPathConstants.NODESET);
        return (NodeList) eval;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

private static void printNode(Node node) throws TransformerFactoryConfigurationError, TransformerException {
    Transformer transformer = TransformerFactory.newInstance().newTransformer();
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
    StreamResult result = new StreamResult(new StringWriter());
    DOMSource source = new DOMSource(node);
    transformer.transform(source, result);
    String xmlString = result.getWriter().toString();
    System.out.println(xmlString);
}

} `

它没有打印任何错误,因为它似乎什么也没做。

【问题讨论】:

  • 你有什么尝试吗?
  • 是的,我做了,查看已编辑的问题以查看我的解决方案
  • 不要将答案编辑到您的问题中。如果您自己的答案与给出的答案足够不同,您可以随时发布。

标签: java xml parsing


【解决方案1】:

你可以用旧的好方法来做。

  1. 将 XML 读取到 DOM
  2. 使用 XPath 提取适当的部分
  3. 打印出来......或做任何你喜欢的事情

代码:

@Test
public void printXml() {
    String yourSampleFile = "52720162.xml";
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    try (InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(yourSampleFile)) {
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.parse(in);
        NodeList list = filterNodesByXPath(doc, "//root/Entity");
        for (int i = 0; i < list.getLength(); i++) {
            Node node = list.item(i);
            printNode(node);
        }
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

private NodeList filterNodesByXPath(Document doc, String xpathExpr) {
    try {
        XPathFactory xPathFactory = XPathFactory.newInstance();
        XPath xpath = xPathFactory.newXPath();
        XPathExpression expr = xpath.compile(xpathExpr);
        Object eval = expr.evaluate(doc, XPathConstants.NODESET);
        return (NodeList) eval;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

private void printNode(Node node) throws TransformerFactoryConfigurationError, TransformerException {
    Transformer transformer = TransformerFactory.newInstance().newTransformer();
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
    StreamResult result = new StreamResult(new StringWriter());
    DOMSource source = new DOMSource(node);
    transformer.transform(source, result);
    String xmlString = result.getWriter().toString();
    System.out.println(xmlString);
}

可以在以下位置找到某种通用形式:How to read XML using XPath in Java

【讨论】:

  • 好的,我要试试你的代码。我会让你知道它是怎么回事。感谢您对我的帖子发表评论
  • 实际上它没有用,从您的代码中我将 String yourSampleFile 更改为我的 xml 文件的完整路径,而且我将方法设为静态,因此我可以从 `public static void main(String[ ] args)` 并且我收到此错误Caused by: java.lang.IllegalArgumentException: InputStream cannot be null。我猜我的文件路径有问题但我不知道是什么,路径正确并且文件也存在
  • 好吧,事实证明问题出在绝对路径上,似乎.getResourceAsStream(yourSampleFile) 将路径读取为从类路径开始的相对路径,所以我将其更改为try (InputStream in = new FileInputStream(filepath)),现在它不会打印任何错误但是我没有看到输出请参阅原始帖子上的编辑以检查 java 代码。
  • 别管我说什么我是个白痴,你的代码很完美我用你的代码创建了一个新类,更改了这一行`NodeList list = filterNodesByXPath(doc, "CISDocument/Entity");` 因为我离开了就像你做的那样,它没有找到节点父结构。谢谢你是我的救星。
  • 酷!有效。我忘了提到我必须包装你的 xml 以使其格式良好。但是你发现了。使用currentThread().getContextClassLoader(),您可以使用一种非常可靠的模式来访问位于 java 类路径上的资源,或者位于与类路径上的目录相关的路径上。
猜你喜欢
  • 1970-01-01
  • 2017-02-25
  • 1970-01-01
  • 1970-01-01
  • 2013-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多