現在、すべてのドキュメントノード(ドキュメント順)のNodeList
を手動で生成しています。私が開始するすべてのドキュメントノードのNodeListを手動で作成する
private static void walkRecursive(Node cur, NodeSet nodes) {
nodes.add(cur);
if (cur.hasAttributes()) {
NamedNodeMap attrs = cur.getAttributes();
for (int i=0; i < attrs.getLength(); i++) {
Node child = attrs.item(i);
walkRecursive(child, nodes);
}
}
int type = cur.getNodeType();
if (type == Node.ELEMENT_NODE || type == Node.DOCUMENT_NODE) {
NodeList children = cur.getChildNodes();
if (children == null)
return;
for (int i=0; i < children.getLength(); i++) {
Node child = children.item(i);
walkRecursive(child, list);
}
}
}
:手動でDOMを歩いて、ノードを収集するため、このNodeList
が
//. | //@* | //namespace::*
である私の最初の試みを(NodeSet
がList
に委任プリミティブNodeList
実装である)を取得するXPath式walkRecursive(doc, nodes)
と呼ぶ再帰は、とnodes
(まだ空の)NodeSet
です。ここでは、doc
です。
<?xml version="1.0"?>
<myns:root xmlns:myns="http://www.my.ns/#">
<myns:element/>
</myns:root>
私は例えば、私の手でNodeSet
を作成し、最初に述べたXPath式によって生成NodeList
とはバイトのための2つのバイトを比較し、その結果を正規化した場合平等で、うまく動作するようです。
しかし私は2つのNodeList
sおよび印刷デバッグ情報(typeString
は、単に文字列表現を生成します)
for (int i=0; i < nodes.getLength(); i++) {
Node child = nodes.item(i);
System.out.println("Type: " + typeString(child.getNodeType()) +
" Name:" + child.getNodeName() +
" Local name: " + child.getLocalName() +
" NS: " + child.getNamespaceURI());
}
を反復処理する場合は、その後、私は、XPath-生成NodeList
ために、この出力を受け取る:
Type: DocumentNode Name:#document Local name: null NS: null
Type: Element Name:myns:root Local name: root NS: http://www.my.ns/#
Type: Attribute Name:xmlns:myns Local name: myns NS: http://www.w3.org/2000/xmlns/
Type: Attribute Name:xmlns:xml Local name: xml NS: http://www.w3.org/2000/xmlns/
Type: Text Name:#text Local name: null NS: null
Type: Element Name:myns:element Local name: element NS: http://www.my.ns/#
Type: Text Name:#text Local name: null NS: null
これは手動で生成されたものです。NodeList
:
Type: DocumentNode Name:#document Local name: null NS: null
Type: Element Name:myns:root Local name: root NS: http://www.my.ns/#
Type: Attribute Name:xmlns:myns Local name: myns NS: http://www.w3.org/2000/xmlns/
Type: Text Name:#text Local name: null NS: null
Type: Element Name:myns:element Local name: element NS: http://www.my.ns/#
Type: Text Name:#text Local name: null NS: null
だから、あなたが見ることができるように、最初の例でのNodeListはさらにXML名前空間のNode
が含まれています
Type: Attribute Name:xmlns:xml Local name: xml NS: http://www.w3.org/2000/xmlns/
今私の質問:
A)私が正しくxml-names11を解釈した場合、 xmlns:xml宣言は必要ありません。
接頭辞xmlは、定義上、名前空間名http://www.w3.org/XML/1998/namespaceにバインドされています。宣言する必要がありますが、宣言する必要はありません。宣言したり、他の名前空間名にバインドしたりしてはいけません。他のプレフィックスは、この名前空間名に束縛されてはならない(MUST NOT)。そして、それはデフォルト名前空間として宣言されてはならない(MUST NOT)。
正しいですか? (少なくともc)その方向のヒント)
b)しかし、XPathの評価では、どうしてそれが追加されるのですか?自動的に物事を追加するのではなく、最初にあったものだけを含めるべきではありませんか?
c)XML canonicalizationで問題が発生する可能性がありますが、shouldn't - 正規化中にxml
の宣言を省略する必要があります。誰かがこれを間違って取得(Java)の実装を知っていますか?
編集:
ここで私は、 'XML' 名前空間ノードに含まれるXPath式を評価するために使用されるコードです:あなたが書くことができますので
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setValidating(false);
InputStream in = ...;
try {
Document doc = dbf.newDocumentBuilder().parse(in);
XPathFactory fac = XPathFactory.newInstance();
XPath xp = fac.newXPath();
XPathExpression exp = xp.compile("//. | //@* | //namespace::*");
NodeList nodes = (NodeList)exp.evaluate(doc, XPathConstants.NODESET);
} finally {
in.close();
}
私はこの余分な属性(jdk1.6.0_18が届かない) –
@Maurice:奇妙なことに、私はJDK 5と7でもそれを手に入れました。私はXPath式を評価するために使ったコードを追加します。 – emboss
私の間違い、あなたの投稿を間違えた –