评估 XPath 并将元素检索到 Java 列表中
Evaluate XPath And Retrieve Elements into Java List
我在 Java 中使用 xPath,我想检索节点 team1_win_perc
、team2_win_perc
和 draw_perc
。这是 xml 文档:
<stats timestamp="1628874073" date="08/13/2021 12:01:13">
<common>
<EV_AVERAGE_HOME>0.006669</EV_AVERAGE_HOME>
<EV_AVERAGE_AWAY>0.00193</EV_AVERAGE_AWAY>
<EV_AVERAGE_DRAW>0.007402678</EV_AVERAGE_DRAW>
</common>
<games>
<id348812>
<gameid gsid="3509729">348812</gameid>
<league>BUND</league>
<team1RotationNumber>150540</team1RotationNumber>
<team1Name>Bayern Munchen</team1Name>
<team1_win_perc>62.1</team1_win_perc>
<team2RotationNumber>150541</team2RotationNumber>
<team2Name>Arsenal</team2Name>
<team2_win_perc>17.8</team2_win_perc>
<draw_perc>20.1</draw_perc>
</id348812>
<id348813>
<gameid gsid="3509730">348813</gameid>
<league>EPL</league>
<team1RotationNumber>150543</team1RotationNumber>
<team1Name>Tottenham</team1Name>
<team1_win_perc>50</team1_win_perc>
<team2RotationNumber>150544</team2RotationNumber>
<team2Name>Chelsea</team2Name>
<team2_win_perc>25</team2_win_perc>
<draw_perc>25</draw_perc>
</id348813>
</games>
</stats>
这是我到目前为止所做的事情:
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
final DocumentBuilder db = dbf.newDocumentBuilder();
final Document document = db.parse(new InputSource(
new ByteArrayInputStream(xmlResponseString.getBytes(UTF_8))));
final XPathFactory xpathFactory = XPathFactory.newInstance();
final XPath xpath = xpathFactory.newXPath();
NodeList gameIds = (NodeList) xpath.evaluate("stats/games/*",
document, NODESET);
final List<Double> homeWinPercentages = new ArrayList<>();
final List<Double> awayWinPercentages = new ArrayList<>();
final List<Double> drawPercentages = new ArrayList<>();
for (int i = 0; i < gameIds.getLength(); ++i) {
Node node = gameIds.item(i);
homeWinPercentages.add(Double.valueOf((String) xpath.evaluate("stats/games/"
+ node.getNodeName() + "/team1_win_perc", document, STRING)));
awayWinPercentages.add(Double.valueOf((String) xpath.evaluate("stats/games/"
+ node.getNodeName() + "/team2_win_perc", document, STRING)));
drawPercentages.add(Double.valueOf((String) xpath.evaluate("stats/games/"
+ node.getNodeName() + "/draw_perc", document, STRING)));
}
有没有办法避免对 xml 文档求值 3 次?我想用 class Probability
创建一个 List
,其中包括字段 team1_win_perc
、team2_win_perc
和 draw_perc
.
我会考虑使用带有 XPath 3.1 的 Saxon 10(或 9.9)HE 来简单地 return 具有三个双值序列的 XPath 3.1 XDM 映射:
import net.sf.saxon.s9api.*;
import java.io.File;
public class Main {
public static void main(String[] args) throws SaxonApiException {
Processor processor = new Processor(false);
DocumentBuilder docBuilder = processor.newDocumentBuilder();
XdmNode inputDoc = docBuilder.build(new File("sample1.xml"));
XdmMap result = (XdmMap) processor.newXPathCompiler().evaluate(
"let $games := stats/games/* return map { 'homeWinPercentages' : $games/team1_win_perc/number(), 'awayWinPercentages' : $games/team2_win_perc/number(), 'drawPercentages' : $games/draw_perc/number() }",
inputDoc
);
System.out.println(result);
}
}
结果输出:
map{"awayWinPercentages":(1.78e1,2.5e1),"drawPercentages":(2.01e1,2.5e1),"homeWinPercentages":(6.21e1,5.0e1)}
我在 Java 中使用 xPath,我想检索节点 team1_win_perc
、team2_win_perc
和 draw_perc
。这是 xml 文档:
<stats timestamp="1628874073" date="08/13/2021 12:01:13">
<common>
<EV_AVERAGE_HOME>0.006669</EV_AVERAGE_HOME>
<EV_AVERAGE_AWAY>0.00193</EV_AVERAGE_AWAY>
<EV_AVERAGE_DRAW>0.007402678</EV_AVERAGE_DRAW>
</common>
<games>
<id348812>
<gameid gsid="3509729">348812</gameid>
<league>BUND</league>
<team1RotationNumber>150540</team1RotationNumber>
<team1Name>Bayern Munchen</team1Name>
<team1_win_perc>62.1</team1_win_perc>
<team2RotationNumber>150541</team2RotationNumber>
<team2Name>Arsenal</team2Name>
<team2_win_perc>17.8</team2_win_perc>
<draw_perc>20.1</draw_perc>
</id348812>
<id348813>
<gameid gsid="3509730">348813</gameid>
<league>EPL</league>
<team1RotationNumber>150543</team1RotationNumber>
<team1Name>Tottenham</team1Name>
<team1_win_perc>50</team1_win_perc>
<team2RotationNumber>150544</team2RotationNumber>
<team2Name>Chelsea</team2Name>
<team2_win_perc>25</team2_win_perc>
<draw_perc>25</draw_perc>
</id348813>
</games>
</stats>
这是我到目前为止所做的事情:
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
final DocumentBuilder db = dbf.newDocumentBuilder();
final Document document = db.parse(new InputSource(
new ByteArrayInputStream(xmlResponseString.getBytes(UTF_8))));
final XPathFactory xpathFactory = XPathFactory.newInstance();
final XPath xpath = xpathFactory.newXPath();
NodeList gameIds = (NodeList) xpath.evaluate("stats/games/*",
document, NODESET);
final List<Double> homeWinPercentages = new ArrayList<>();
final List<Double> awayWinPercentages = new ArrayList<>();
final List<Double> drawPercentages = new ArrayList<>();
for (int i = 0; i < gameIds.getLength(); ++i) {
Node node = gameIds.item(i);
homeWinPercentages.add(Double.valueOf((String) xpath.evaluate("stats/games/"
+ node.getNodeName() + "/team1_win_perc", document, STRING)));
awayWinPercentages.add(Double.valueOf((String) xpath.evaluate("stats/games/"
+ node.getNodeName() + "/team2_win_perc", document, STRING)));
drawPercentages.add(Double.valueOf((String) xpath.evaluate("stats/games/"
+ node.getNodeName() + "/draw_perc", document, STRING)));
}
有没有办法避免对 xml 文档求值 3 次?我想用 class Probability
创建一个 List
,其中包括字段 team1_win_perc
、team2_win_perc
和 draw_perc
.
我会考虑使用带有 XPath 3.1 的 Saxon 10(或 9.9)HE 来简单地 return 具有三个双值序列的 XPath 3.1 XDM 映射:
import net.sf.saxon.s9api.*;
import java.io.File;
public class Main {
public static void main(String[] args) throws SaxonApiException {
Processor processor = new Processor(false);
DocumentBuilder docBuilder = processor.newDocumentBuilder();
XdmNode inputDoc = docBuilder.build(new File("sample1.xml"));
XdmMap result = (XdmMap) processor.newXPathCompiler().evaluate(
"let $games := stats/games/* return map { 'homeWinPercentages' : $games/team1_win_perc/number(), 'awayWinPercentages' : $games/team2_win_perc/number(), 'drawPercentages' : $games/draw_perc/number() }",
inputDoc
);
System.out.println(result);
}
}
结果输出:
map{"awayWinPercentages":(1.78e1,2.5e1),"drawPercentages":(2.01e1,2.5e1),"homeWinPercentages":(6.21e1,5.0e1)}