我有一个输入 XML
<Request>
<Info>
<Country>US</Country>
<Part>A</Part>
</Info>
</Request>
我的输出应该是这样的
<Request
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://hgkl.kj.com">
<Info>
<Country>US</Country>
<Part>A</Part>
</Info>
</Request>
请让我知道如何添加多个命名空间和默认命名空间,如上面的 XML。
这是我在 XSLT 2.0 中的做法...
XML 输入
<Request>
<Info>
<Country>US</Country>
<Part>A</Part>
</Info>
</Request>
XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*" priority="1">
<xsl:element name="{local-name()}" namespace="http://hgkl.kj.com">
<xsl:namespace name="xsi" select="'http://www.w3.org/2001/XMLSchema-instance'"/>
<xsl:namespace name="xsd" select="'http://www.w3.org/2001/XMLSchema'"/>
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
XML 输出
<Request xmlns="http://hgkl.kj.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Info>
<Country>US</Country>
<Part>A</Part>
</Info>
</Request>
这里有一个 XSLT 1.0 选项,它会产生相同的输出,但要求您知道根元素的名称...
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|text()|comment()|processing-instruction()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/Request">
<Request xmlns="http://hgkl.kj.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsl:apply-templates select="@*|node()"/>
</Request>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}" namespace="http://hgkl.kj.com">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
这个答案显然没有优化,但会提示您如何让它在 4.2 版本的命名空间和非命名空间 XML 上工作:
这里是
parseXml
的body方法
JAXBContext jc = JAXBContext.newInstance(VAST.class);
Unmarshaller u = jc.createUnmarshaller();
// should be optimized
TransformerFactory tf = TransformerFactory.newInstance();
StringWriter sw = new StringWriter();
URL urlXslt = VastParser.class.getClassLoader().getResource("xslt/vast_4.2.xslt");
File fileXslt = new File(urlXslt.toURI());
Transformer t = tf.newTransformer(new StreamSource(new FileInputStream(fileXslt)));
// transform original XML with XSLT to always add the namespace in the parsing
t.transform(new StreamSource(new StringReader(xmlString)), new StreamResult(sw));
// unmarshall transformed XML
JAXBElement<VAST> foo = u.unmarshal(new StreamSource(new StringReader(sw.toString())), VAST.class);
return new CustomVast(foo.getValue());
src/main/resources/xslt/vast_4.2.xslt
是:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|text()|comment()|processing-instruction()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- adds the xmlns part to the VAST element -->
<xsl:template match="/VAST">
<VAST xmlns="http://www.iab.com/VAST">
<xsl:apply-templates select="@*|node()"/>
</VAST>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这样,两个单元测试都适用于 4.2 部分。