2016-11-15 4 views
2

У меня есть строка XML.Сплит XML с использованием JDOM Java

<Engineers> 
    <Engineer> 
     <Name>JOHN</Name> 
     <Position>STL</Position> 
     <Team>SS</Team> 
    </Engineer> 
    <Engineer> 
     <Name>UDAY</Name> 
     <Position>TL</Position> 
     <Team>SG</Team> 
    </Engineer> 
    <Engineer> 
     <Name>INDRA</Name> 
     <Position>Director</Position> 
     <Team>PP</Team> 
    </Engineer> 
</Engineers> 

Мне нужно разделить этот XML на более мелкие строки XML, когда Xpath даются как инженеры/Enginner.

Меньшие строки XML являются

<Engineer> 
     <Name>INDRA</Name> 
     <Position>Director</Position> 
     <Team>PP</Team> 
    </Engineer> 

<Engineer> 
     <Name>JOHN</Name> 
     <Position>STL</Position> 
     <Team>SS</Team> 
</Engineer> 

я реализовал следующие используя саксонских и JDOM XPath.

import net.sf.saxon.Configuration; 
import net.sf.saxon.lib.NamespaceConstant; 
import net.sf.saxon.om.DocumentInfo; 
import net.sf.saxon.om.NodeInfo; 
import net.sf.saxon.s9api.DocumentBuilder; 
import net.sf.saxon.s9api.XPathCompiler; 
import net.sf.saxon.s9api.XPathSelector; 
import net.sf.saxon.s9api.XdmNode; 
import net.sf.saxon.xpath.XPathFactoryImpl; 
import org.apache.axiom.om.OMElement; 
import org.apache.axiom.om.impl.builder.StAXOMBuilder; 
import org.junit.Test; 
import org.xml.sax.InputSource; 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.StringReader; 
import java.util.Iterator; 
import java.util.List; 
import javax.xml.transform.sax.SAXSource; 
import javax.xml.transform.stream.StreamSource; 
import javax.xml.xpath.XPath; 
import javax.xml.xpath.XPathConstants; 
import javax.xml.xpath.XPathExpression; 
import javax.xml.xpath.XPathExpressionException; 
import javax.xml.xpath.XPathFactory; 
import javax.xml.xpath.XPathFactoryConfigurationException; 

public void testXML() throws XPathFactoryConfigurationException, XPathExpressionException, Exception { 

     System.setProperty("javax.xml.xpath.XPathFactory:" + NamespaceConstant.OBJECT_MODEL_JDOM, 
       "net.sf.saxon.xpath.XPathFactoryImpl"); 
     XPathFactory xPathFactory = XPathFactory.newInstance(NamespaceConstant.OBJECT_MODEL_JDOM); 
     XPath xPath = xPathFactory.newXPath(); 
     InputSource inputSource = new InputSource(new File(filename).toURI().toString()); 
     SAXSource saxSource = new SAXSource(inputSource); 
     Configuration config = ((XPathFactoryImpl) xPathFactory).getConfiguration(); 
     DocumentInfo document = config.buildDocument(saxSource); 
     XPathExpression xPathExpression = xPath.compile("//Engineers/Engineer"); 
     List matches = (List) xPathExpression.evaluate(document, XPathConstants.NODESET); 
     if (matches != null) { 
      for (Iterator iter = matches.iterator(); iter.hasNext();) { 
       NodeInfo node = (NodeInfo) iter.next(); 
       System.out.println(node.getDisplayName() + " - " + node.getStringValue()); 
      } 
     } 

    } 

Это дает следующий результат.

Engineer - 
     JOHN 
     STL 
     SS 

Engineer - 
     UDAY 
     TL 
     SG 

Engineer - 
     INDRA 
     Director 
     PP 

Как я могу изменить код так, что я получу желаемый результат? Или есть способ получить имена детских атрибутов (имя, должность, команда) внутри инженера

ответ

1

Если вы используете JDOM для этой работы, вы должны рассмотреть использование собственных методов JDOM вместо абстракции, проходящей через Saxon.

Рассмотрим что-то вроде:

import org.jdom2.Document; 
import org.jdom2.Element; 
import org.jdom2.xpath.XPathFactory; 
import org.jdom2.xpath.XPAthExpression; 
import org.jdom2.output.XMLOutputter; 
import org.jdom2.input.SAXBuilder; 
import org.jdom2.filter.Filters; 

.... 

    XPathExpression xpe = XPathFactory.instance() 
     .compile("//Engineers/Engineer", Filters.element()); 

    Document doc = new SAXBuilder().build(new File(filename)); 

    XMLOutputter xout = new XMLOutputter(Format.getPrettyFormat()); 

    for (Element e : xpe.evaluate(doc)) { 
     xout.output(e, System.out); 
    } 
1

Я бы расщепление в XSLT:

<xsl:stylesheet ....> 
<xsl:template match="Engineeers/Engineer"> 
    <xsl:result-document href="{position()}.xml"> 
    <xsl:copy-of select="."/> 
    </xsl:result-document> 
</xsl:template> 
</xsl:stylesheet> 

Если вы хотите результат в виде списка JDOM документов, то вы можете поставить Saxon с OutputURIResolver:

Controller controller = transformer.getUnderlyingController(); 
final Configuration config = controller.getConfiguration(); 
List<Document> jdomDocuments = new ArrayLis<Document>(); 
Controller.setOutputURIResolver(new OutputURIResolver() { 

    public Result resolve(href, base) { 
     return new JDOM2Writer(config.makePipelineConfiguration()); 
    } 

    public void close(Result result) { 
     jdomDocuments.add(((JDOM2Writer)result).getDocument()); 
    } 
} 

и по завершении результаты будут представлены в jdomDocuments.