Я сделал минимальный пример, чтобы воспроизвести проблему. Это преобразование (mini.xsl):java copy-of xsl transform удаляет префикс пространства имен
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<foo>
<xsl:copy-of select="."/>
</foo>
</xsl:template>
</xsl:stylesheet>
и это вход (mini.xml):
<?xml version="1.0" encoding="utf-8"?>
<bar xmlns:x="baz">
<x:baz/>
</bar>
Когда я применить преобразование с
xsltproc mini.xsl mini.xml
Результат выглядит как ожидалось:
<?xml version="1.0"?>
<foo>
<bar xmlns:x="baz">
<x:baz/>
</bar>
</foo>
Ho Веверу, когда я бегу преобразование с помощью следующей программы Java,
import java.io.FileInputStream;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
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.SAXException;
public class Program
{
public static void main(String[] args)
{
try
{
Source transform = new StreamSource(new FileInputStream(args[0]));
Templates templates = TransformerFactory.newInstance().newTemplates(transform);
Document input = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new FileInputStream(args[1]));
Result result = new StreamResult(System.out);
templates.newTransformer().transform(new DOMSource(input), result);
}
catch (TransformerFactoryConfigurationError | ParserConfigurationException | SAXException | IOException | TransformerException e)
{
e.printStackTrace();
}
}
}
результат выглядит следующим образом:
<?xml version="1.0" encoding="UTF-8"?>
<foo>
<bar xmlns:x="baz">
<baz/>
</bar>
</foo>
(обратите внимание, что х:. префикс перед БАЗ отсутствует)
Почему?
И что я могу с этим сделать (чтобы сохранить префикс пространства имен)?
Лучше все же передать StreamSource в метод transform() вместо DOM. DOM и XSLT на самом деле не так хорошо сочетаются, и большинство процессоров XSLT будут работать намного лучше, если вы разрешите им самим строить дерево. –