如何在Java中的XSLT转换期间提供(xmlns)命名空间

时间:2013-02-18 22:39:16

标签: java xml xslt transform

我需要转换到xml(没有命名空间)

XML:

<?xml version="1.0" encoding="UTF-8"?>
<policy>
 <num-drivers>123</num-drivers>
 <risk-policy-ind>false</policy-ind>
 <premium-amt>23.00</premium-amt>
</policy>

风格:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" 
xmlns="http://aaa.bbb.com" xmlns:ptws="http://aaa.bbb.com" exclude-result-prefixes="xs fn xsl">
<xsl:namespace-alias stylesheet-prefix="ptws" result-prefix="#default"/>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" xpath-default-namespace="http://aaa.bbb.com"/>
<xsl:template match="/">
    <xsl:apply-templates/>
</xsl:template>
<xsl:template match="ptws:policy">
<auto-policy-dto>
    <xsl:copy-of select="ptws:num-drivers"/>
    <xsl:copy-of select="ptws:risk-policy-ind"/>
    <xsl:copy-of select="ptws:premium-amt"/>
</policy>
</xsl:template>

JAVA代码:

TransformerFactory tfactory = TransformerFactory.newInstance();
Source xslt = new StreamSource(IN_XSLT_FILE_NAME);
Transformer transformer = tfactory.newTransformer(xslt);

SAXSource source = new SAXSource(
                XMLReaderFactory.createXMLReader(),
                new InputSource(IN_XML_FILE_NAME));
transformer.transform(source, new StreamResult(OUT_XML_FILE_NAME)); 

OUTPUT xml:

<?xml version="1.0" encoding="UTF-8"?>
    123
    false
    23.00

output.xml中缺少元素。如何在转换时提供名称空间“http://aaa.bbb.com”?

预期的Output.xml:

<?xml version="1.0" encoding="UTF-8"?><ptws:policy xmlns:ptws="http://aaa.bbb.com">
  <num-drivers xmlns="http://aaa.bbb.com">123</num-drivers>
  <risk-policy-ind xmlns="http://aaa.bbb.com">false</risk-policy-ind>
  <premium-amt xmlns="http://aaa.bbb.com">23.00</premium-amt>
</ptws:policy>

我试着这样做:

public class XMLUtilsTest {

   private static final String IN_XML_FILE_NAME = "C:/sampleXML.xml";
   private static final String IN_XSLT_FILE_NAME = "C:/sample.xslt";

   private static final String OUT_XML_FILE_NAME = "C:/rc/output.xml";

   public static Boolean transformXML() throws SAXException, IOException, URISyntaxException, TransformerException {

    try {
        TransformerFactory tfactory = TransformerFactory.newInstance();
        Source xslt = new StreamSource(IN_XSLT_FILE_NAME);
        Transformer transformer = tfactory.newTransformer(xslt);

        SAXSource source = new SAXSource(
                new NamespaceFilter(XMLReaderFactory.createXMLReader()),
                new InputSource(IN_XML_FILE_NAME));
        transformer.transform(source, new StreamResult(OUT_XML_FILE_NAME));            
    }
    catch(Exception ex){
        System.out.println(ex.getMessage()); 
    }                    

  }

protected static class NamespaceFilter extends XMLFilterImpl {

    String requiredNamespace = "http://aaa.bbb.com";

    public NamespaceFilter(XMLReader parent) {
        super(parent);
    }

    @Override
    public void startElement(String arg0, String arg1, String arg2, Attributes arg3) throws SAXException {
        if(arg0 != requiredNamespace) arg0 = requiredNamespace;
        super.startElement(arg0, arg1, arg2, arg3);
    }       
}
}

但这会生成以下xml。仍缺少元素

<?xml version="1.0" encoding="UTF-8"?><ptws:policy xmlns:ptws="http://aaa.bbb.com">
< xmlns="http://aaa.bbb.com">123</>
< xmlns="http://aaa.bbb.com">false</>
< xmlns="http://aaa.bbb.com">23.00</>
</ptws:policy>

1 个答案:

答案 0 :(得分:0)

我认为你只是想改变所有元素的命名空间?

 <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ptws="http://aaa.bbb.com"
    exclude-result-prefixes="xsl">

  <xsl:template match="node()|@*">
      <xsl:copy>
          <xsl:apply-templates select="node()|@*" />
      </xsl:copy>
  </xsl:template>

  <xsl:template match="*">
      <xsl:element name="ptws:{local-name()}">
          <xsl:apply-templates select="node()|@*"/>
      </xsl:element>
  </xsl:template>

</xsl:stylesheet>

模板不起作用的原因是<xsl:template match="ptws:policy">与任何内容都不匹配,默认模板只复制文本节点。