getNodeName、getLocalName 未返回预期值
getNodeName, getLocalName not returning expected values
我正在解析一个简单的 XML 并尝试获取节点名称。在此 XML 的某些变体中,某些节点名称具有命名空间前缀 "mets:"。我正在尝试匹配所有 "fptr" 元素,无论它们是否具有 mets 前缀。
这里是 xml 的示例,其中包含简单的 fptr 元素和一些带有前缀的元素:
<mets:structMap xmlns:mets="http://www.loc.gov/METS/" xmlns="http://www.loc.gov/METS/" TYPE="logical" ID="DTL1">
<div ORDER="1" LABEL="Alle Scans" TYPE="first level" ID="DTL2">
<div ORDER="1" LABEL="1" TYPE="Seite" ID="DTL3">
<mets:fptr FILEID="FID00000020" ID="DTL21"/>
</div>
<div ORDER="2" LABEL="2" TYPE="Seite" ID="DTL4">
<mets:fptr FILEID="FID00000021" ID="DTL22"/>
</div>
</div>
<div ORDER="1" LABEL="Hauptdokument - pdf" TYPE="entry" ID="DTL5">
<fptr FILEID="FID1a" ID="DTL11"/>
</div>
</mets:structMap>
这是一个简单的解析例程,应该打印出所有元素的元素名称和 ns-prefix:
package at.ac.onb.zid.dtlcontent.test;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class structMapTest {
public static void main(String args[]) throws ParserConfigurationException, SAXException, IOException {
File fXmlFile = new File("src/test/resources/teststructmap.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
NodeList elemList = doc.getElementsByTagName("*");
for(int i = 0; i<elemList.getLength();i++) {
Node n = elemList.item(i);
System.out.println("nodeName=" + n.getNodeName());
if(n instanceof Element) {
Element e = (Element) n;
String eID = e.getAttribute("ID");
String nsPrefix = e.getPrefix();
String eLN = e.getLocalName();
String eNSURI = e.getNamespaceURI();
System.out.println(" ID=" + eID);
System.out.println(" prefix=" + nsPrefix);
System.out.println(" localName=" + eLN);
System.out.println(" nsURI=" + eNSURI);
System.out.println("");
}
}
}
}
这是它打印出来的内容:
nodeName=mets:structMap
ID=DTL1
prefix=null
localName=null
nsURI=null
nodeName=div
ID=DTL2
prefix=null
localName=null
nsURI=null
nodeName=div
ID=DTL3
prefix=null
localName=null
nsURI=null
nodeName=mets:fptr
ID=DTL21
prefix=null
localName=null
nsURI=null
nodeName=div
ID=DTL4
prefix=null
localName=null
nsURI=null
nodeName=mets:fptr
ID=DTL22
prefix=null
localName=null
nsURI=null
nodeName=div
ID=DTL5
prefix=null
localName=null
nsURI=null
nodeName=fptr
ID=DTL11
prefix=null
localName=null
nsURI=null
所有前缀值为空。我预计前两个 fptr 前缀(ID=DTL21 和 DTL22)是 "mets"。
与 localName 相同:我希望所有 fptr-localName 都是 "fptr",但它们都是空的。与名称空间 URI 类似。
我在这里错过了什么?
确保在尝试以有意义的方式使用带有名称空间的 XML 之前设置 dbFactory.setNamespaceAware(true);
。
XML 命名空间非常明智,就像 XML 的大部分设计一样,而且确实像 XML 的大部分设计一样,直接在代码。在您的示例中,前缀元素和非前缀元素实际上是相同的命名空间 URL,因此您根本不应该有任何问题。
Java 8 library Dynamics 默认忽略命名空间(但如果需要可以显式显示,即在它真正重要的极少数情况下)。该库不是一种查询语言,只是一种处理动态结构的非常直接的方式。由于这样递归很容易,所以我们可以这样扫描所有元素:
{
XmlDynamic example = new XmlDynamic(xmlStringOrReaderOrInputSourceEtc);
List<String> ids = allElements(example)
.filter(hasElementName("fptr")) // import static alexh.weak.XmlDynamic.hasElementName;
.map(fptr -> fptr.get("@ID").asString())
.collect(toList());
// [DTL21, DTL22, DTL11]
}
/** recursively stream all elements */
Stream<Dynamic> allElements(Dynamic root) {
return Stream.concat(Stream.of(root), root.children().flatMap(child -> allElements(child)));
}
我正在解析一个简单的 XML 并尝试获取节点名称。在此 XML 的某些变体中,某些节点名称具有命名空间前缀 "mets:"。我正在尝试匹配所有 "fptr" 元素,无论它们是否具有 mets 前缀。
这里是 xml 的示例,其中包含简单的 fptr 元素和一些带有前缀的元素:
<mets:structMap xmlns:mets="http://www.loc.gov/METS/" xmlns="http://www.loc.gov/METS/" TYPE="logical" ID="DTL1">
<div ORDER="1" LABEL="Alle Scans" TYPE="first level" ID="DTL2">
<div ORDER="1" LABEL="1" TYPE="Seite" ID="DTL3">
<mets:fptr FILEID="FID00000020" ID="DTL21"/>
</div>
<div ORDER="2" LABEL="2" TYPE="Seite" ID="DTL4">
<mets:fptr FILEID="FID00000021" ID="DTL22"/>
</div>
</div>
<div ORDER="1" LABEL="Hauptdokument - pdf" TYPE="entry" ID="DTL5">
<fptr FILEID="FID1a" ID="DTL11"/>
</div>
</mets:structMap>
这是一个简单的解析例程,应该打印出所有元素的元素名称和 ns-prefix:
package at.ac.onb.zid.dtlcontent.test;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class structMapTest {
public static void main(String args[]) throws ParserConfigurationException, SAXException, IOException {
File fXmlFile = new File("src/test/resources/teststructmap.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
NodeList elemList = doc.getElementsByTagName("*");
for(int i = 0; i<elemList.getLength();i++) {
Node n = elemList.item(i);
System.out.println("nodeName=" + n.getNodeName());
if(n instanceof Element) {
Element e = (Element) n;
String eID = e.getAttribute("ID");
String nsPrefix = e.getPrefix();
String eLN = e.getLocalName();
String eNSURI = e.getNamespaceURI();
System.out.println(" ID=" + eID);
System.out.println(" prefix=" + nsPrefix);
System.out.println(" localName=" + eLN);
System.out.println(" nsURI=" + eNSURI);
System.out.println("");
}
}
}
}
这是它打印出来的内容:
nodeName=mets:structMap
ID=DTL1
prefix=null
localName=null
nsURI=null
nodeName=div
ID=DTL2
prefix=null
localName=null
nsURI=null
nodeName=div
ID=DTL3
prefix=null
localName=null
nsURI=null
nodeName=mets:fptr
ID=DTL21
prefix=null
localName=null
nsURI=null
nodeName=div
ID=DTL4
prefix=null
localName=null
nsURI=null
nodeName=mets:fptr
ID=DTL22
prefix=null
localName=null
nsURI=null
nodeName=div
ID=DTL5
prefix=null
localName=null
nsURI=null
nodeName=fptr
ID=DTL11
prefix=null
localName=null
nsURI=null
所有前缀值为空。我预计前两个 fptr 前缀(ID=DTL21 和 DTL22)是 "mets"。
与 localName 相同:我希望所有 fptr-localName 都是 "fptr",但它们都是空的。与名称空间 URI 类似。
我在这里错过了什么?
确保在尝试以有意义的方式使用带有名称空间的 XML 之前设置 dbFactory.setNamespaceAware(true);
。
XML 命名空间非常明智,就像 XML 的大部分设计一样,而且确实像 XML 的大部分设计一样,直接在代码。在您的示例中,前缀元素和非前缀元素实际上是相同的命名空间 URL,因此您根本不应该有任何问题。
Java 8 library Dynamics 默认忽略命名空间(但如果需要可以显式显示,即在它真正重要的极少数情况下)。该库不是一种查询语言,只是一种处理动态结构的非常直接的方式。由于这样递归很容易,所以我们可以这样扫描所有元素:
{
XmlDynamic example = new XmlDynamic(xmlStringOrReaderOrInputSourceEtc);
List<String> ids = allElements(example)
.filter(hasElementName("fptr")) // import static alexh.weak.XmlDynamic.hasElementName;
.map(fptr -> fptr.get("@ID").asString())
.collect(toList());
// [DTL21, DTL22, DTL11]
}
/** recursively stream all elements */
Stream<Dynamic> allElements(Dynamic root) {
return Stream.concat(Stream.of(root), root.children().flatMap(child -> allElements(child)));
}