如何分配名称空间前缀&使用XSLT从一个xml到另一个xml的namespace属性

时间:2014-05-20 15:52:43

标签: xml xslt

是否可以转换INPUT XML,这样就可以使用TEMPLATE XML中指定的名称空间,名称空间前缀来丰富INPUT XML中的所有元素。这可以通过XSLT实现吗?请帮忙。

输入XML:


<?xml version="1.0" encoding="UTF-8"?>
<getCustomerInfoInput>
    <Address>
        <City>Ams</City>
        <Street>Cnet st</Street>
    </Address>
    <Address>
        <City>Lon</City>
        <Street>high st</Street>
    </Address>
    <CustomerId>12345</CustomerId>
    <Name>
        <FirstName>first</FirstName>
        <LastName>last</LastName>
    </Name>
</getCustomerInfoInput>

模板XML:


<?xml version="1.0" encoding="UTF-8"?>
<ns0:getCustomerInfoInput xmlns:ns0="http://www.example.com/schemas/Service/MediumLevelSchema/getCusotmerInfoSchema.xsd">
    <ns0:Name>
        <ns1:FirstName xmlns:ns1="http://www.example.com/schemas/Service/MediumLevelSchema/GenericInfoSchema.xsd"/>
        <ns1:LastName xmlns:ns1="http://www.example.com/schemas/Service/MediumLevelSchema/GenericInfoSchema.xsd"/>
    </ns0:Name>
    <ns0:Address>
        <ns0:Street/>
        <ns0:City/>
    </ns0:Address>
    <ns0:CustomerId/>
</ns0:getCustomerInfoInput>

预期结果:


<?xml version="1.0" encoding="UTF-8">
<ns0:getCustomerInfoInput xmlns:ns0="http://www.example.com/schemas/Service/MediumLevelSchema/getCusotmerInfoSchema.xsd">
    <ns0:Name>
        <ns1:FirstName xmlns:ns1="http://www.example.com/schemas/Service/MediumLevelSchema/GenericInfoSchema.xsd">first</ns1:FirstName>
        <ns1:LastName xmlns:ns1="http://www.example.com/schemas/Service/MediumLevelSchema/GenericInfoSchema.xsd">last</ns1:LastName>
    </ns0:Name>
    <ns0:Address>
        <ns0:Street>Cnet st</ns0:Street>
        <ns0:City>Ams</ns0:City>
    </ns0:Address>
    <ns0:Address>
        <ns0:Street>high st</ns0:Street>
        <ns0:City>Lon</ns0:City>
    </ns0:Address>
    <ns0:CustomerId>12345</ns0:CustomerId>
</ns0:getCustomerInfoInput>

我之前尝试用Java实现这个,但它没有' 产生预期的结果。

我最初尝试使用Java实现这一点(下面给出完整的代码)。我在尝试的逻辑:遍历INPUT和TEMPLATE XML的所有节点。如果元素名称在两者中都匹配,则为相应元素选取名称空间,名称空间前缀,并将其设置为INPUT XML节点。 这几乎对我有用,除了它,它不允许我使用setPrefix()。因此,生成的XML文档看起来与我想要的类似,但在所有元素中都没有名称空间前缀。由于这在Java中变得过于复杂(尝试了各种其他选项),我已经开始寻找像XSLT这样的选项。到目前为止我从未使用过XSLT。任何有关XSLT的帮助都将不胜感激。

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPathExpressionException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.traversal.DocumentTraversal;
import org.w3c.dom.traversal.NodeFilter;
import org.w3c.dom.traversal.NodeIterator;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class EnrichXML {

    public static void main(String[] args) throws XPathExpressionException, SAXException, ParserConfigurationException, IOException, Exception {

        String dataXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><getCustomerInfoInput><Address><City>Ams</City><Street>high st</Street></Address><Address><City>Lon</City><Street>central st</Street></Address><CustomerId>12345</CustomerId><Name><FirstName>first</FirstName><LastName>last</LastName></Name></getCustomerInfoInput>";
        System.out.println("Data XML: " + dataXML);
        Document dataXMLDocument = stringToDom(dataXML);

        String templateXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <ns0:getCustomerInfoInput xmlns:ns0=\"http://www.example.com/schemas/MediumLevelSchema/getCusotmerInfoSchema.xsd\">     <ns0:Name>         <ns1:FirstName xmlns:ns1=\"http://www.example.com/schemas/MediumLevelSchema/GenericInfoSchema.xsd\"/>         <ns1:LastName xmlns:ns1=\"http://www.example.com/schemas/MediumLevelSchema/GenericInfoSchema.xsd\"/>     </ns0:Name>     <ns0:Address>         <ns0:Street/>         <ns0:City/>     </ns0:Address>     <ns0:CustomerId/> </ns0:getCustomerInfoInput>";
        System.out.println("Template XML: " + templateXML);
        Document templateXMLDocument = stringToDom(templateXML);
        templateXMLDocument.getDocumentElement().normalize();

        DocumentTraversal docTraversalDataXML = (DocumentTraversal) dataXMLDocument;
        NodeIterator nodeItrDataXML = docTraversalDataXML.createNodeIterator(dataXMLDocument.getDocumentElement(), NodeFilter.SHOW_ELEMENT, null, true);

        for (Element dataXMLNode = (Element)nodeItrDataXML.nextNode(); dataXMLNode != null; dataXMLNode=(Element)nodeItrDataXML.nextNode()) {

            DocumentTraversal docTraversalTemplateXML = (DocumentTraversal) templateXMLDocument;
            NodeIterator nodeItrTemplateXML = docTraversalTemplateXML.createNodeIterator(templateXMLDocument.getDocumentElement(), NodeFilter.SHOW_ELEMENT, null, true);

            for (Node templateXMLnode = nodeItrTemplateXML.nextNode(); templateXMLnode != null; templateXMLnode=nodeItrTemplateXML.nextNode()) {

                if(dataXMLNode.getLocalName().equalsIgnoreCase(templateXMLnode.getLocalName()) && dataXMLNode.getPrefix() == null) {
                    dataXMLNode.setAttribute("xmlns:"+templateXMLnode.getPrefix(), templateXMLnode.getNamespaceURI());
                    //dataXMLNode.setPrefix(templateXMLnode.getPrefix());
                }

            }
        }
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer transformer = tf.newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
        StringWriter writer = new StringWriter();
        transformer.transform(new DOMSource(dataXMLDocument), new StreamResult(writer));
        String xmlString = writer.getBuffer().toString().replaceAll("\n|\r", "");
        System.out.println("Final XML: "+xmlString);
    }
    public static Document stringToDom(String xmlSource) 
            throws SAXException, ParserConfigurationException, IOException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        DocumentBuilder builder = factory.newDocumentBuilder();
        return builder.parse(new InputSource(new StringReader(xmlSource)));
    }

}

此Java代码生成此结果:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<getCustomerInfoInput xmlns:ns0="http://www.example.com/schemas/MediumLevelSchema/getCusotmerInfoSchema.xsd">
    <Address>
        <City>Ams</City>
        <Street>high st</Street>
    </Address>
    <Address>
        <City>Lon</City>
        <Street>central st</Street>
    </Address>
    <CustomerId>12345</CustomerId>
    <Name>
        <FirstName xmlns:ns1="http://www.example.com/schemas/MediumLevelSchema/GenericInfoSchema.xsd">first</FirstName>
        <LastName xmlns:ns1="http://www.example.com/schemas/MediumLevelSchema/GenericInfoSchema.xsd">last</LastName>
    </Name>
</getCustomerInfoInput>

0 个答案:

没有答案