[英]How to include namespace in XSL transformation in XML
我正在尝试使用JAVA将xml文件转换为另一个xml文件。 转换后,新的xml将具有一组子元素和所需的名称空间。 但是,我无法包含所需的特定名称空间。 要么全有要么全无。 有人可以帮忙吗?
输入XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:root
xmlns="http://uri1.com"
xmlns:ns2="http://uri2.com">
<element1>
<elementA1>
<elementB1>AA</elementB1>
</elementA1>
<elementA2>12345</elementA2>
<elementA3>A 000</elementA3>
</element1>
</ns2:root>
预期输出XML
<?xml version="1.0" encoding="UTF-8"?>
<element1 xmlns="http://uri1.com" >
<elementA1>
<elementB1>AA</elementB1>
</elementA1>
<elementA2>12345</elementA2>
<elementA3>A 000</elementA3>
</element1>
我正在使用的XSL文件
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- <xsl:output method="xml" omit-xml-declaration="yes" encoding="utf-8"/> -->
<!-- For each element, create a new element with the same local-name (no namespace) -->
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<!-- Skip the root element, just process its children. -->
<xsl:template match="/*">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
当前输出XML(不带名称空间)
<?xml version="1.0" encoding="UTF-8"?>
<element1>
<elementA1>
<elementB1>AA</elementB1>
</elementA1>
<elementA2>12345</elementA2>
<elementA3>A 000</elementA3>
</element1>
用于执行XSL转换的Java代码
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.transform.Templates;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
public final class XsltTransformer {
private Templates templates;
public XsltTransformer(final String xslFilePath) {
String xslt = FileUtils.getAsString(xslFilePath);
try {
this.templates = TransformerFactory.newInstance().newTemplates(new StreamSource(new StringReader(xslt)));
} catch (Exception e) {
throw new IllegalArgumentException("Error while creating XLST transformer with XSLT text [" + xslt + "]", e);
}
}
public String applyTransformation(final String inputXml) {
try {
StreamSource in = new StreamSource(new StringReader(inputXml));
StreamResult out = new StreamResult(new StringWriter());
templates.newTransformer().transform(in, out);
return out.getWriter().toString();
} catch (Exception e) {
throw new IllegalArgumentException("Unable to transform input XML [" + inputXml + "]", e);
}
}
}
有人可以帮我添加预期的输出XML中的特定名称空间吗? 谢谢 !
所以最后我找到了一种使用默认名称空间来破解结果的方法。 上面所有的答案都很好,并且这个答案也适用于Java Transformation。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="http://uri1.com"
xmlns:ns2="http://uri2.com">
<!-- For each element, create a new element with the same local-name (no namespace) -->
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<!-- Skip the root element, just process its children. -->
<xsl:template match="/*">
<xsl:apply-templates/>
</xsl:template>
<!--override the new root element and insert the default namespace -->
<xsl:template match="/ns2:root/ns1:element1">
<xsl:element name="element1"
xmlns="http://uri1.com">
<xsl:apply-templates select="@* | node()" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
在样式表标签中,将默认名称空间声明为:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://uri1.com">
只需删除根包装即可获得所需的结果:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<xsl:copy-of select="*"/>
</xsl:template>
</xsl:stylesheet>
请注意,这将留下冗余的名称空间声明xmlns:ns2="http://uri2.com"
但这应该不成问题,除非您的目标应用程序不符合要求。
这是一个可以准确给出您期望结果的转换。
在样式表中,如果需要查找特定元素,则必须重新声明输入文档中存在的命名空间。 然后,您可以使用前缀 (例如ns1:
引用命名空间中的元素。
当使用xsl:element
构造新元素时,可以添加一个属性namespace
,这将为新元素生成默认的命名空间 。
样式表
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns2="http://uri2.com">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="*">
<xsl:element name="{local-name()}" namespace="http://uri1.com">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="/ns2:root">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
XML输出
<?xml version="1.0" encoding="UTF-8"?>
<element1 xmlns="http://uri1.com">
<elementA1>
<elementB1>AA</elementB1>
</elementA1>
<elementA2>12345</elementA2>
<elementA3>A 000</elementA3>
</element1>
在这里在线尝试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.