这是我项目的摘录:
import javafx.util.Pair;
import org.w3c.dom.*;
private Pair<Element, Integer> findBestAlbumElement(Element recording) {
Pair<Element, Integer> best = new Pair<>(null, Integer.MIN_VALUE);
NodeList list = recording.getElementsByTagName("release");
for (int i = 0; i < list.getLength(); i++) {
System.out.println((best.getKey() == null ? "null" : best.getKey().getTextContent()) + "; " + best.getValue());
Element album = (Element) list.item(i);
int mark = getAlbumAndYearMark(recording, album);
if (mark > best.getValue()) best = new Pair<>(album, mark);
System.out.println((best.getKey() == null ? "null" : best.getKey().getTextContent()) + "; " + best.getValue());
}
return best;
}
我在这段代码中遇到了一个奇怪的问题。变量best
在循环迭代之间重置,如打印输出到控制台的开头所示:
空; -2147483648
Live USABootlegAlbumLive1990DE1990GermanyGermanyDE212CD2T.N.T255240; 6
空; -2147483648
...
第一行是第一行System.out.println()
,第二行是第二行(变量best
按预期正确设置),第三行是第一行(变量所在的位置) best
似乎只是自行重置。)
我尝试使用以下代码复制问题:
Pair<String, Integer> best = new Pair<>("", Integer.MIN_VALUE);
String[] strings = {"asdf", "fdsa", "dsaf"};
int[] marks = {1, 5, 3};
for (int i = 0; i < strings.length; i++) {
System.out.println(best.getKey() + " " + best.getValue());
if (marks[i] > best.getValue()) best = new Pair<>(strings[i], marks[i]);
System.out.println(best.getKey() + " " + best.getValue());
}
用NodeList
数组替换String
,但此代码按预期工作。
我的问题是,我甚至不知道如何解决这个问题。我不知道如何进一步调试,甚至在一个较小的例子中重现问题,因为我不知道如何创建一个有效的NodeList
(因为它是一个接口,所以我不能只是{{ 1}})。
我也有点不知所措,因为它让我觉得这个错误出现在一个它甚至不可能的地方,因为唯一的代码应该在两个{{1之间执行调用是new NodeList
(不以任何方式改变甚至访问println
)。我错了吗?
有没有人知道会发生什么,甚至我怎么会更接近找出问题?
根据请求,这里是i++
,它使用best
库(对于丑陋的长行代码道歉,这是一个相当古老的项目)。
getAlbumAndYearMark
但我不相信这种方法存在问题,因为如果我将jaudiotagger
替换为private Tag tag;
private int getAlbumAndYearMark(Element recording, Element album) {
int mark = 0;
if (album == null) return tag.hasField(FieldKey.YEAR) ? getYearMark(album) : 0;
if (contains(album.getElementsByTagName("primary-type"), "Album")) mark += 2;
else if (!contains(album.getElementsByTagName("secondary-type"), "Album")) return Integer.MIN_VALUE;
Node title = album.getElementsByTagName("title").item(0);
if (title != null && tag.hasField(FieldKey.ALBUM)) mark += title.getTextContent().equals(tag.getFirst(FieldKey.ALBUM)) ? 7 : -4;
Node date = album.getElementsByTagName("date").item(0);
if (date != null && tag.hasField(FieldKey.YEAR)) mark += date.getTextContent().equals(tag.getFirst(FieldKey.YEAR).trim()) ? 3 : -3;
Node track = album.getElementsByTagName("number").item(0);
if (track != null && tag.hasField(FieldKey.TRACK)) mark += track.getTextContent().equals(tag.getFirst(FieldKey.TRACK).trim()) ? 3 : -1;
return mark;
}
private int getYearMark(Element element) {
NodeList dates = element.getElementsByTagName("date");
for (int i = 0; i < dates.getLength(); i++)
if (dates.item(i).getTextContent().substring(0, 4).equals(tag.getFirst(FieldKey.YEAR))) return 7;
return -7;
}
private static boolean contains(NodeList list, String string) {
for (int i = 0; i < list.getLength(); i++)
if (list.item(i).getTextContent().trim().equalsIgnoreCase(string)) return true;
return false;
}
这是一个(经过严格修整的)示例XML文件,直接从程序中打印出来:
int mark = getAlbumYearMark(recording, album);
您可以通过直接查询musicbrainz数据库来查看未修剪的示例,例如this query。
答案 0 :(得分:0)
这还不是答案。我尝试使用下一个xml:
<root>
<release-list>
<release id="ddaa5690-df97-4bb2-b93d-396fe5fb49d5">
<title>Live USA</title>
<date>1990</date>
<country>DE</country>
</release>
<release id="qqqa5690-df97-4bb2-b93d-396fe5fb49d5">
<title>German collections</title>
<date>1991</date>
<country>DE</country>
</release>
</release-list>
<release-list>
<release id="zzza5690-df97-4bb2-b93d-396fe5fb49d5">
<title>Just USA</title>
<date>1995</date>
<country>US</country>
</release>
</release-list>
<release-list>
<release id="aaaa5690-df97-4bb2-b93d-396fe5fb49d5">
<title>Anoother USA</title>
<primary-type>Album</primary-type>
<date>1999</date>
<country>RUS</country>
</release>
</release-list>
我没有问题。你可以尝试使用这个xml吗?
此外,我还使用了像return mockMark++;
这样的增量标记和基于数组的标记
private int getAlbumAndYearMark(Element recording, Element album) {
int[] arr = {1,0,5,7,3,6,8,9,10};
return arr[mockMark++];
}