2016-05-20 7 views
3

Я хотел бы удалить атрибут xmlns из следующей строки XML. Я написал программу java, но не уверен, что она делает то, что нужно сделать здесь.Как удалить атрибут xmlns из корневого элемента в xml и java

Как удалить атрибут xmlns и получить измененную строку xml?

Входная строка XML:

<?xml version="1.0" encoding="UTF-8"?> 
<Payment xmlns="http://api.com/schema/store/1.0"> 
    <Store>abc</Store> 
</Payment> 

Ожидаемый XML Выходная строка:

<?xml version="1.0" encoding="UTF-8"?> 
<Payment> 
    <Store>abc</Store> 
</Payment> 

Java Класс:

public class XPathUtils { 

    public static void main(String[] args) { 
     String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Payment xmlns=\"http://api.com/schema/store/1.0\"><Store>abc</Store></Payment>"; 
     String afterNsRemoval = removeNameSpace(xml); 
     System.out.println("afterNsRemoval = " + afterNsRemoval); 
    } 

    public static String removeNameSpace(String xml) { 
     try { 
      System.out.println("before xml = " + xml); 
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
      DocumentBuilder builder = factory.newDocumentBuilder(); 
      InputSource inputSource = new InputSource(new StringReader(xml)); 
      Document xmlDoc = builder.parse(inputSource); 
      Node root = xmlDoc.getDocumentElement(); 
      NodeList rootchildren = root.getChildNodes(); 
      Element newroot = xmlDoc.createElement(root.getNodeName()); 
      for (int i = 0; i < rootchildren.getLength(); i++) { 
       newroot.appendChild(rootchildren.item(i).cloneNode(true)); 
      } 
      xmlDoc.replaceChild(newroot, root); 
      return xmlDoc.toString(); 
     } catch (Exception e) { 
      System.out.println("Could not parse message as xml: " + e.getMessage()); 
     } 
     return ""; 
    } 
} 

Выход:

before xml = <?xml version="1.0" encoding="UTF-8"?><Payment xmlns="http://api.com/schema/store/1.0"><Store>abc</Store></Payment> 

afterNsRemoval = [#document: null] 
+0

Почему бы вам не использовать выражение XPath, чтобы помочь решению узлов атрибутов ... в ВТД-XML эта задача является эффективным 10 строк короткого кода ... –

+0

я буду более чем счастлив, чтобы попробовать его , Любые указатели на то, как это можно реализовать? – user2325154

+0

gimme несколько минут ... красота с xpath заключается в том, что вы можете эффективно удалить все атрибуты по вашему выбору ... даже для очень сложного документа ... xpath не более чем «// @ *» ... –

ответ

1

Это код, чтобы сделать это с помощью XPath и ВТД-XML (из которых я являюсь автором) ...

import com.ximpleware.*; 
import java.io.*; 

public class removeAttrNode { 
    public static void main(String[] s) throws VTDException, Exception{ 
     VTDGen vg = new VTDGen(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Payment xmlns=\"http://api.com/schema/store/1.0\"><Store>abc</Store></Payment>"; 
     vg.setDoc(xml.getBytes()); 
     vg.parse(false); // turn off namespace awareness so that 
     VTDNav vn = vg.getNav(); 
     AutoPilot ap = new AutoPilot(vn); 
     XMLModifier xm = new XMLModifier(vn); 
     ap.selectXPath("//@xmlns"); 
     int i=0; 
     while((i=ap.evalXPath())!=-1){ 
      xm.remove(); 
     } 
     xm.output(baos); 
     System.out.println(baos.toString());  
    } 
} 
+0

Является ли 'com.ximpleware' третьей стороной lib, доступной на mvn repo? – user2325154

+0

Да, и на sourceforge, а также http://vtd-xml.sf.net –

+1

Вы хотите, чтобы кто-то использовал стороннюю библиотеку для решения такого простого варианта использования? – SomeDude

2

Вам нужен трансформатор. Проверьте ниже модифицированного метода:

public static String removeNameSpace(String xml) { 


     try { 
      TransformerFactory tf = TransformerFactory.newInstance(); 
      Transformer transformer = tf.newTransformer(); 
      transformer.setOutputProperty(OutputKeys.METHOD, "xml"); 
      transformer.setOutputProperty(OutputKeys.INDENT, "false"); 
      System.out.println("before xml = " + xml); 
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
      DocumentBuilder builder = factory.newDocumentBuilder(); 
      InputSource inputSource = new InputSource(new StringReader(xml)); 
      Document xmlDoc = builder.parse(inputSource); 
      Node root = xmlDoc.getDocumentElement(); 
      NodeList rootchildren = root.getChildNodes(); 
      Element newroot = xmlDoc.createElement(root.getNodeName()); 
      for (int i = 0; i < rootchildren.getLength(); i++) { 
       newroot.appendChild(rootchildren.item(i).cloneNode(true)); 
      } 
      xmlDoc.replaceChild(newroot, root); 
      DOMSource requestXMLSource = new DOMSource(xmlDoc.getDocumentElement()); 
      StringWriter requestXMLStringWriter = new StringWriter(); 
      StreamResult requestXMLStreamResult = new StreamResult(requestXMLStringWriter);    
      transformer.transform(requestXMLSource, requestXMLStreamResult); 
      String modifiedRequestXML = requestXMLStringWriter.toString(); 

      return modifiedRequestXML; 
     } catch (Exception e) { 
      System.out.println("Could not parse message as xml: " + e.getMessage()); 
     } 
     return ""; 
    } 

Выход:

before xml = <?xml version="1.0" encoding="UTF-8"?><Payment xmlns="http://api.com/schema/store/1.0"><Store>abc</Store></Payment> 
afterNsRemoval = <?xml version="1.0" encoding="UTF-8"?><Payment><Store>abc</Store></Payment> 
+0

Код DOM наверняка выглядит немного уродливым для меня ... –

+0

Всегда можно сделать это кратким. – SomeDude

1

Вы все сделали правильно, за исключением последнего действия: document.toString() дает неправильный результат, потому что это неправильный способ получения строки XML представление Document объекта , См этой answer, она содержит правильное применение этого метода:

public static String toString(Document doc) { 
    try { 
     StringWriter sw = new StringWriter(); 
     TransformerFactory tf = TransformerFactory.newInstance(); 
     ... 
0

Рассмотрим XSLT, поскольку удаление объявленного/незанятого пространства имен является обычной задачей. Здесь нет сторонних модулей, поскольку базовая Java оснащена процессором XSLT 1.0. Кроме того, никакие циклы или XML-тэги/атрибуты воссоздания не обрабатываются, поскольку XSLT заботится о преобразовании.

import java.io.*; 

import javax.xml.parsers.*; 
import javax.xml.transform.*; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 
import javax.xml.transform.stream.StreamSource; 

import org.w3c.dom.Document; 
import org.xml.sax.InputSource; 
import org.xml.sax.SAXException; 

public class XPathUtils { 
    public static void main(String[] args) { 

     String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Payment xmlns=\"http://api.com/schema/store/1.0\"><Store>abc</Store></Payment>"; 
     String afterNsRemoval = removeNameSpace(xml); 
     System.out.println("afterNsRemoval = " + afterNsRemoval); 
    } 

    public static String removeNameSpace(String xml) { 
     try{ 
      String xslStr = String.join("\n", 
       "<xsl:transform xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">", 
       "<xsl:output version=\"1.0\" encoding=\"UTF-8\" indent=\"no\"/>", 
       "<xsl:strip-space elements=\"*\"/>",       
       " <xsl:template match=\"@*|node()\">", 
       " <xsl:element name=\"{local-name()}\">", 
       "  <xsl:apply-templates select=\"@*|node()\"/>", 
       " </xsl:element>", 
       " </xsl:template>", 
       " <xsl:template match=\"text()\">", 
       " <xsl:copy/>", 
       " </xsl:template>",         
       "</xsl:transform>"); 

      // Parse XML and Build Document 
      DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 
      InputSource is = new InputSource(); 
      is.setCharacterStream(new StringReader(xml)); 
      Document doc = db.parse (is);      

      // Parse XSLT and Configure Transformer 
      Source xslt = new StreamSource(new StringReader(xslStr)); 
      Transformer tf = TransformerFactory.newInstance().newTransformer(xslt); 

      // Output Result to String 
      DOMSource source = new DOMSource(doc); 
      StringWriter outWriter = new StringWriter(); 
      StreamResult strresult = new StreamResult(outWriter);   
      tf.transform(source, strresult); 
      StringBuffer sb = outWriter.getBuffer(); 
      String finalstring = sb.toString(); 

      return(finalstring); 

     } catch (Exception e) { 
      System.out.println("Could not parse message as xml: " + e.getMessage()); 
     } 
      return "";  
    } 
}