如何通过XPATH解析XML文件

时间:2015-10-01 19:19:59

标签: java xml parsing xpath

我想解析这个XML文件:

<?xml version="1.0"?>
<Gist xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../schema/Gist.xsd">
    <Name>AboveOrEqualToThreshold</Name>
    <Version>1</Version>
    <Tags>
        <Tag>Comparison</Tag>
    </Tags>
    <Description>Determines if a value is at or over a threshold or not.</Description>
    <Configuration />
    <OutputType>
        <ScalarType>Boolean</ScalarType>
    </OutputType>
    <PertinentData>
        <Item>
            <Name>ValueMinusThreshold</Name>
        </Item>
        <Item>
            <Name>ThresholdMinusValue</Name>
        </Item>
    </PertinentData>
    <Scenarios>
        <Scenario>
            <ID>THRESHOLD_DOES_NOT_APPLY</ID>
            <Description>The threshold does not apply.</Description>
        </Scenario>
        <Scenario>
            <ID>ABOVE_THRESHOLD</ID>
            <Description>The value is above the threshold.</Description>
        </Scenario>
        <Scenario>
            <ID>EQUAL_TO_THRESHOLD</ID>
            <Description>The value is equal to the threshold.</Description>
        </Scenario>
        <Scenario>
            <ID>NOT_ABOVE_THRESHOLD</ID>
            <Description>The value is not above the threshold.</Description>
        </Scenario>
    </Scenarios>
</Gist>

要在此XPATH / Gist / Name中获取该值,因此对于此文件,它将是一个字符串:

  • AboveOrEqualToThreshold

以及此XPATH Gist / Scenarios / Scenario / ID / *中此文件的方案,因此对于此文件,它将是一个字符串列表:

  • THRESHOLD_DOES_NOT_APPLY

  • ABOVE_THRESHOLD

  • EQUAL_TO_THRESHOLD

  • NOT_ABOVE_THRESHOLD

所以这个的数据结构是:

Map<String,List<String>>

我怎样才能在Java中实现这一点,这看起来非常简单,但我没有成功实现这一目标。

非常感谢任何帮助或帮助。

我的实施尝试:

static Map<Node, Node> parseScenarioByGist(String filename) throws IOException, XPathException {

    XPath xpath = XPathFactory.newInstance().newXPath();
    Map<Node, Node> scenarioByGist = new LinkedHashMap<Node, Node>();

    try (InputStream file = new BufferedInputStream(Files.newInputStream(Paths.get(filename)))) {

        NodeList nodes = (NodeList) xpath.evaluate("//Gist", new InputSource(file), XPathConstants.NODESET);
        int nodeCount = nodes.getLength();

        for (int i = 0; i < nodeCount; i++) {
            Node node = nodes.item(i);


            Node gist = (Node) xpath.evaluate("Gist/Name", node, XPathConstants.NODE);//String node.getAttributes().getNamedItem("name").getNodeValue();
            Node scenario = (Node) xpath.evaluate("Gist/Scenarios/Scenario/ID/*", node, XPathConstants.NODE);

            scenarioByGist.put(gist, scenario);
        }
    }

    return scenarioByGist;
}

1 个答案:

答案 0 :(得分:1)

我假设你说你需要输出

Map<String, List<String>>
你的意思是

Map<Name, List<Scenarios>>

(如果我错了,请纠正我!!!)。我使用Conversion Box在此基础上写了一些东西。看看......

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cjm.component.cb.map.ToMap;

public class DummyClass
{
public static void main(String[] args)
{
    try
    {
        String xml = "<?xml version=\"1.0\"?><Gist xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"../schema/Gist.xsd\"><Name>AboveOrEqualToThreshold</Name><Version>1</Version><Tags><Tag>Comparison</Tag></Tags><Description>Determines if a value is at or over a threshold or not.</Description><Configuration /><OutputType><ScalarType>Boolean</ScalarType></OutputType><PertinentData><Item><Name>ValueMinusThreshold</Name></Item><Item><Name>ThresholdMinusValue</Name></Item></PertinentData><Scenarios><Scenario><ID>THRESHOLD_DOES_NOT_APPLY</ID><Description>The threshold does not apply.</Description></Scenario><Scenario><ID>ABOVE_THRESHOLD</ID><Description>The value is above the threshold.</Description></Scenario><Scenario><ID>EQUAL_TO_THRESHOLD</ID><Description>The value is equal to the threshold.</Description></Scenario><Scenario><ID>NOT_ABOVE_THRESHOLD</ID><Description>The value is not above the threshold.</Description></Scenario></Scenarios></Gist>";

        Map<String, Object> map = (new ToMap()).convertToMap(xml); // Conversion Box

        Map<String, Object> mapGist = (Map<String, Object>) map.get("Gist");

        String name = (String) mapGist.get("Name");

        List<Map<String, Object>> scenarioMapList = (List<Map<String, Object>>) mapGist.get("Scenarios");

        List<String> scenarioList = new ArrayList<String>();

        for (int index = 0; index < scenarioMapList.size(); index++)
        {
            Map<String, Object> scenarioMap = scenarioMapList.get(index);

            scenarioList.add((String) scenarioMap.get("ID"));
        }

        Map<String, List<String>> whatMosawiWants = new HashMap<String, List<String>>();

        whatMosawiWants.put(name, scenarioList);

        System.out.println("What Mosawi wants: " + whatMosawiWants);
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}
}

输出:

 -------- XML Detected -------- 
 -------- Map created Successfully -------- 
What Mosawi wants: {AboveOrEqualToThreshold=[THRESHOLD_DOES_NOT_APPLY, ABOVE_THRESHOLD, EQUAL_TO_THRESHOLD, NOT_ABOVE_THRESHOLD]}