2016-04-10 2 views
1

J'ai un fichier xml, mentionné ci-dessous:Java: analyse du fichier XML en utilisant SAX/XPATH

<?xml version="1.0" encoding="UTF-8"?> 
<Workbook> 
    <ExcelWorkbook 
    xmlns="urn:schemas-microsoft-com:office:excel"/> 
     <Worksheet ss:Name="Table 1"> 
      <Table> 
       <Row ss:Index="7" ss:AutoFitHeight="0" ss:Height="12"> 
       <Cell ss:Index="1" ss:StyleID="s05"> 
        <ss:Data ss:Type="String" 
         xmlns="http://www.w3.org/TR/REC-html40"> 
         <Font html:Size="9" html:Face="Times New Roman" x:Family="Roman" html:Color="#000000"> 
         ABCD 
         </Font> 
        </ss:Data> 
       </Cell> 
      </Row> 

Comment puis-je extraire les données, "ABCD" ici, en utilisant SAX ou XPATH en Java?

EDIT 1:

C'est le langage XML

<Table> 
<Row ss:Index="74" ss:AutoFitHeight="0" ss:Height="14"> 
    <Cell ss:Index="1" ss:MergeAcross="3" ss:StyleID="s29"> 
     <ss:Data ss:Type="Number" xmlns="http://www.w3.org/TR/REC-html40"> 
     0.00 
     </ss:Data> 
    </Cell> 
    <Cell ss:Index="15" ss:MergeAcross="5" ss:StyleID="s29"> 
     <ss:Data ss:Type="Number" xmlns="http://www.w3.org/TR/REC-html40"> 
     4.57 
     </ss:Data> 
    </Cell> 
</Row> 
+1

est-ce que ça doit être SAX? XPATH est beaucoup mieux adapté pour la recherche dans le document XML –

+0

@sharonbn XPATH ira bien, mais je ne suis pas du tout familier avec elle. Pouvez vous me donner un coup de main? – Dax

+0

@sharonbn J'ai modifié votre code. 'String cellStringContent ="/* [@ ss: Type = 'Numéro']/* [texte()]/text() ";'. Mais cela donne une erreur ici: 'if (n.getNodeType() == Node.TEXT_NODE)'. Au lieu de TEXT_NODE j'ai essayé d'utiliser d'autres constantes nommées nodeType, mais cela n'a pas fonctionné. S'il vous plaît aider. – Dax

Répondre

1

La solution suppose que la question est de savoir comment obtenir le texte pour une cellule en fonction du nombre de lignes et de colonnes.

Il m'a fallu un certain temps pour obtenir la solution à cause de l'utilisation des espaces de noms dans le document d'entrée. apparemment, xpath ne peut pas analyser les éléments et les attributs qualifiés sans un processeur d'espace de noms et un hsa pour implémenter une interface à cet effet (il n'y a pas de valeur par défaut?), donc j'ai trouvé une implémentation basée sur la carte here. Donc, en supposant que vous ayez la classe du lien dans votre arbre source, le code suivant fonctionne. Je me suis cassé le modèle de recherche à plusieurs variables pour un souci de clarté

public static String getCellValue(String filename, int rowIdx, int colIdx) { 
    // search for Table element anywhere in the source 
    String tableElementPattern = "//*[name()='Table']"; 
    // search for Row element with given number 
    String rowPattern = String.format("/*[name()='Row' and @ss:Index='%d']", rowIdx) ; 
    // search for Cell element with given column number 
    String cellPattern = String.format("/*[name()='Cell' and @ss:Index='%d']", colIdx) ; 
    // search for element that has ss:Type="String" attribute, search for element with text under it and get text name 
    String cellStringContent = "/*[@ss:Type='String']/*[text()]/text()"; 
    String completePattern = tableElementPattern + rowPattern + cellPattern + cellStringContent; 

    try (FileReader reader = new FileReader(filename)) { 
     XPath xPath = getXpathProcessor(); 
     Node n = (Node)xPath.compile(completePattern) 
     .evaluate(new InputSource(reader), XPathConstants.NODE); 
     if (n.getNodeType() == Node.TEXT_NODE) { 
      return n.getNodeValue().trim(); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 

private static XPath getXpathProcessor() { 
    // this is where the custom implementation of NamespaceContext is used 
    NamespaceContext context = new NamespaceContextMap(
     "html", "http://www.w3.org/TR/REC-html40", 
     "xsl", "http://www.w3.org/1999/XSL/Transform", 
     "o", "urn:schemas-microsoft-com:office:office", 
     "x", "urn:schemas-microsoft-com:office:excel", 
     "ss", "urn:schemas-microsoft-com:office:spreadsheet"); 
    XPath xpath = XPathFactory.newInstance().newXPath(); 
    xpath.setNamespaceContext(context); 
    return xpath; 
} 

appelant:

System.out.println(getCellValue("C://Temp/xx.xml", 7, 1)); 

produit la sortie désirée

+0

Cela a fonctionné. Merci beaucoup! – Dax

0

Voici le code pour faire interroger votre XML avec vtd-xml ..

import com.ximpleware.*; 

public class queryXML{ 

public static void main(String[] s) throws VTDException{ 

     VTDGen vg = new VTDGen(); 
     vg.selectLcDepth(5); 
     if (!vg.parseFile("d:\\xml\\test11.xml", false)) 
      return; 
     VTDNav vn = vg.getNav(); 
     AutoPilot ap = new AutoPilot(vn); 
     ap.declareNameSpace("ss","urn:schemas-microsoft-com:office:spreadsheet"); 
       ap.selectXPath("/Workbook/ExcelWorkbook/Worksheet/Table/Cell/ss:data/font/text()"); 
int i=0; 
while((i=ap.evalXPath())!=-1){ 
System.out.println(" data content ==>"+vn.toString(i); 
} 


} 


}