Почему xmlns =»» автоматически добавляются к элементу в Java?

#java #xml #namespaces

#java #xml #пространства имен

Вопрос:

Я создаю XML-файл с использованием Java. Я создал корневой узел, используя createElemenNS(), чтобы создать корневой узел с пространством имен.

 Element root = doc.createElementNS("http://www.myorc.com/schemas", "InvConf");
  

Затем я создал узел с помощью createElement() и добавил его в корневой узел. Этот узел автоматически добавляется с пространством имен, как показано ниже.

  Element invList = doc.createElement("InvList");
 root.appendChild(invList);

<InvConf xmlns="http://www.myorc.com/schemas">
   <InvList xmlns="">
   ...
   </InvList>
   <InvList xmlns="">
   ...
   </InvList>
   <InvList xmlns="">
   ...
   </InvList>
</InvConf>
  

Как избежать добавления пространства имен к дочерним узлам?
Я хочу, чтобы конечный XML был следующим

 <InvConf xmlns="http://www.myorc.com/schemas">
   <InvList>
   ...
   </InvList>
   <InvList>
   ...
   </InvList>
   <InvList>
   ...
   </InvList>
</InvConf>
  

Обнаружено, что проблемы возникают только тогда, когда xmlparserv2.jar находится в ПУТИ к КЛАССУ. Это требуется для некоторых частей приложения. Как это решить?

Комментарии:

1. У дочерних узлов не будет указанного пространства имен, если оно находится в том же пространстве имен, что и родительский узел.

2. xmlns=»» не добавляет пространство имен, оно его удаляет. Он был помещен туда, потому что вы создали элемент, который не находится в том же пространстве имен, что и его родительский.

Ответ №1:

Xmlns =»» были добавлены, потому что ваш дочерний элемент не находится в пространстве имен, а ваш родитель. Чтобы изменить это, поместите его в пространство имен во время создания элемента. Измените

 createElement("InvList");
  

В правильное пространство имен.

Ответ №2:

Как указано в комментариях xmlns="" , означает, что элемент не имеет никакого пространства имен. Например. с точки зрения синтаксического анализатора XML следующие два документа идентичны:

 <ns:root xmlns:ns="http://namespace.com">
    <child/>
</ns:root>
  

и

 <root xmlns="http://namespace.com">
    <child xmlns=""/>
</root>
  

Чтобы избежать создания элементов xmlns="" in, не принадлежащих ни к одному пространству имен, вы можете создать префикс для элемента верхнего уровня:

 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
    
Document doc = db.newDocument();
Element root = doc.createElementNS("http://namespace.com", "root");
root.setPrefix("ns");
Element child = doc.createElementNS("", "child");
root.appendChild(child);
doc.appendChild(root);
  

Этот код создаст следующий XML:

 <ns:root xmlns:ns="http://namespace.com">
    <child/>
</ns:root>
  

В качестве альтернативы вы можете использовать следующий синтаксис для достижения того же результата:

 Document doc = db.newDocument();
Element root = doc.createElementNS("http://namespace.com", "ns:root");
Element child = doc.createElementNS("", "child");
root.appendChild(child);
doc.appendChild(root);
  

При комментировании строки root.setPrefix("ns"); или создании элемента без префикса ( doc.createElementNS("http://namespace.com", "root"); ) будет сгенерирован следующий XML:

 <root xmlns="http://namespace.com">
    <child xmlns=""/>
</root>
  

Комментарии:

1. Разве дочерний элемент не должен наследовать родительское пространство имен? Почему нам нужно явно указывать это?

2. Это именно тот случай. Вы объявляете пространство имен по умолчанию (пространство имен без префикса) для родительского, и по умолчанию все дочерние элементы должны принадлежать одному и тому же пространству имен. Если они этого не делают, xmlns="" генерируется, чтобы показать, что они не принадлежат родительскому пространству имен.

3. Хорошо. Как избежать добавления xmlns=»» к дочерним элементам. Конечный XML не должен содержать этого в дочерних элементах.

4. Это зависит. Если дочерние элементы должны находиться в том же пространстве имен, что и родительские, создайте их таким же образом, используя createElementNS() родительское пространство имен. Если у них не должно быть пространства имен, определите префикс пространства имен на родительском уровне, как описано в ответе.