我希望从net.sf.saxon.s9api.XdmNode中的一个标签中读取所有名称空间。我可以使用下面的代码读取它们,但由于性能问题,我应该使用现有的DOM来解析和读取命名空间。
input.xml中
<?xml version="1.0" encoding="utf-8"?>
<?taxonomy-version 2.2.3.0?> <?taxonomy-set-overall-version 2.6.0.0?>
<!--(C) EBA-->
<link:linkbase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:link="http://www.xbrl.org/2003/linkbase" xmlns:gen="http://xbrl.org/2008/generic" xmlns:label="http://xbrl.org/2008/label" xmlns:formula="http://xbrl.org/2008/formula" xmlns:df="http://xbrl.org/2008/filter/dimension" xmlns:table="http://xbrl.org/2014/table" xmlns:model="http://www.eurofiling.info/xbrl/ext/model" xmlns:eba_dim="http://www.eba.europa.eu/xbrl/crr/dict/dim" xmlns:eba_PL="http://www.eba.europa.eu/xbrl/crr/dict/dom/PL" xmlns:eba_met="http://www.eba.europa.eu/xbrl/crr/dict/met" xmlns:eba_BA="http://www.eba.europa.eu/xbrl/crr/dict/dom/BA" xmlns:eba_MC="http://www.eba.europa.eu/xbrl/crr/dict/dom/MC" xmlns:eba_IM="http://www.eba.europa.eu/xbrl/crr/dict/dom/IM" xmlns:eba_AP="http://www.eba.europa.eu/xbrl/crr/dict/dom/AP" xmlns:eba_TR="http://www.eba.europa.eu/xbrl/crr/dict/dom/TR" xmlns:eba_EC="http://www.eba.europa.eu/xbrl/crr/dict/dom/EC" xmlns:eba_CT="http://www.eba.europa.eu/xbrl/crr/dict/dom/CT" xmlns:eba_GA="http://www.eba.europa.eu/xbrl/crr/dict/dom/GA" xsi:schemaLocation="http://www.xbrl.org/2003/linkbase http://www.xbrl.org/2003/xbrl-linkbase-2003-12-31.xsd http://xbrl.org/2008/generic http://www.xbrl.org/2008/generic-link.xsd http://xbrl.org/2008/label http://www.xbrl.org/2008/generic-label.xsd http://xbrl.org/2008/formula http://www.xbrl.org/2008/formula.xsd http://xbrl.org/2008/filter/dimension http://www.xbrl.org/2008/dimension-filter.xsd http://xbrl.org/2014/table http://www.xbrl.org/2014/table.xsd http://www.eurofiling.info/xbrl/ext/model http://www.eurofiling.info/eu/fr/xbrl/ext/model.xsd">
<link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2014/aspect-node-filter" xlink:type="simple" xlink:href="http://www.xbrl.org/2014/table.xsd#aspect-node-filter" />
<link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2014/breakdown-tree" xlink:type="simple" xlink:href="http://www.xbrl.org/2014/table.xsd#breakdown-tree" />
<link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2014/definition-node-subtree" xlink:type="simple" xlink:href="http://www.xbrl.org/2014/table.xsd#definition-node-subtree" />
<link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2014/table-breakdown" xlink:type="simple" xlink:href="http://www.xbrl.org/2014/table.xsd#table-breakdown" />
<link:roleRef roleURI="http://www.eba.europa.eu/xbrl/crr/role/dict/dom/GA/GA5_1" xlink:type="simple" xlink:href="../../../../../../dict/dom/ga/hier.xsd#eba_GA5_1" />
<link:roleRef roleURI="http://www.eba.europa.eu/xbrl/crr/role/fws/COREP/its-2016-03/2016-11-15/tab/C_09.01.a" xlink:type="simple" xlink:href="c_09.01.a.xsd#role" />
</link:linkbase>
从上面的文件中,我希望从link:linkbase标签中读取所有“xmlns”属性。
以下代码段按预期工作但达到了性能。
代码
private List<Namespace> getNameSpaceListFromFile() throws ValidationException {
List <Namespace>nsList = new ArrayList<Namespace>();
try {
if(inputFile!=null){
BufferedReader bufferedReader = new BufferedReader(new FileReader(inputFile)); //I18NOK:IOE
String line;
StringBuilder stringBuilder = new StringBuilder();
while((line=bufferedReader.readLine())!= null){
stringBuilder.append(line.trim());
}
XMLStreamReader reader = XMLInputFactory.newFactory().createXMLStreamReader(new StringReader(stringBuilder.toString().trim().replaceFirst("^([\\W]+)<","<"))); /*I18NOK:LSM*/ //removing byte order markers by using "^([\\W]+)<","<"
while (reader.hasNext()) {
int event = reader.next();
if (XMLStreamConstants.START_ELEMENT == event) {
if (reader.getNamespaceCount() > 0) {
for (int nsIndex = 0; nsIndex < reader.getNamespaceCount(); nsIndex++) {
System.out.println(reader.getNamespacePrefix(nsIndex).trim()+"\t\t:\t\t"+ reader.getNamespaceURI(nsIndex).trim());
nsList.add(new Namespace(reader.getNamespacePrefix(nsIndex).trim(), reader.getNamespaceURI(nsIndex).trim()));
}
}
}
}
bufferedReader.close();
}
if(nsList.isEmpty()){
return new NamespaceLoader(context).getNsListFromProperties();
}
} catch (Exception e) {
e.printStackTrace();
}
return nsList;
}
我搜索了正确的工作解决方案,但找不到任何。
Iterator <XdmItem> itemList = document.axisIterator(Axis.CHILD);
while(itemList.hasNext()) {
XdmItem item = itemList.next();
System.err.println(item.getStringValue());
}
在上面的代码中,我在XdmItem中获得了完整的“link”标记,但是找不到一种方法来读取linkbase标记并获取命名空间。
任何形式的帮助将不胜感激。另外,如果需要更多信息,请告诉我。
答案 0 :(得分:1)
如果我理解正确,您已将该文档作为XdmNode的实例保存。如果是这种情况,那么您可以使用s9api接口来执行XPath表达式
/*/namespace(*)
这将返回一个XdmValue,其中包含最外层元素上的命名空间节点列表。然后你可以做
for (XdmItem item : result) {
XdmNode ns = (XdmNode)item;
String prefix = ns.getNodeName()==null ? "" : ns.getNodeName().getLocalName();
String uri = ns.getStringValue();
...
}
如果您愿意,可以通过在文档节点上使用XdmNode.axisIterator(Axis.CHILD)
来查找最外层元素,然后XdmNode.axisIterator(Axis.NAMESPACE)
来查找命名空间节点,从而达到相同的效果。