将XML元素作为字符串提取,包括使用Stax的属性名称空间



给定以下XML字符串

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:a="http://a" xmlns:b="http://b">
  <a:element b:attribute="value">
    <subelement/>
  </a:element>
</root>

我想在使用stax保存使用的名称空间时将元素a:element提取为XML字符串。所以我希望

<?xml version="1.0" encoding="UTF-8"?>
<a:element xmlns:a="http://a" xmlns:b="http://b" b:attribute="value">
  <subelement/>
</a:element>

https://stackoverflow.com/a/5170415/2391901和https://stackoverflow.com/a/a/4353531/2391901等以下答案。

final ByteArrayInputStream inputStream = new ByteArrayInputStream(inputString.getBytes(StandardCharsets.UTF_8));
final XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
final XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(inputStream);
xmlStreamReader.nextTag();
xmlStreamReader.nextTag();
final TransformerFactory transformerFactory = TransformerFactory.newInstance();
final Transformer transformer = transformerFactory.newTransformer();
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
transformer.transform(new StAXSource(xmlStreamReader), new StreamResult(outputStream));
final String outputString = outputStream.toString(StandardCharsets.UTF_8.name());

但是,结果不包含属性b:attribute的命名空间http://b(使用Java 8的默认Stax Parser或AALTO XML的Stax Parser):

<?xml version="1.0" encoding="UTF-8"?>
<a:element xmlns:a="http://a" b:attribute="value">
  <subelement/>
</a:element>

如何使用Stax获得预期的结果?

使用XSLT变换来做到这一点,这将是清洁的。您已经使用了身份变压器来执行输出 - 只需将其设置为复制目标元素而不是所有内容:

public static void main(String[] args) throws TransformerException {
    String inputString =
        "<root xmlns:a='http://a' xmlns:b='http://b'>" +
        "  <a:element b:attribute='value'>" +
        "    <subelement/>" +
        "  </a:element>" +
        "</root>";
    String xslt = 
        "<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:a='http://a'>" +
        "    <xsl:template match='/root'>" +
        "        <xsl:copy-of select='a:element'/>" +
        "    </xsl:template>" +
        "</xsl:stylesheet>";
    TransformerFactory transformerFactory = TransformerFactory.newInstance();
    Transformer transformer = transformerFactory.newTransformer(new StreamSource(new StringReader(xslt)));
    transformer.transform(new StreamSource(new StringReader(inputString)), new StreamResult(System.out));
}

您正在使用的Stax子树变换依赖于使用JDK发出的变压器的某些行为。当我尝试使用撒克逊变压器(抱怨</root>)时,它无效。

最新更新