2017-10-11 6 views
-1

ich eine XML-Datei wie die folgende haben:benötigen XML mit HTML-Elemente zu analysieren

<?xml version="1.0"?> 
<Book> 
    <Title>Ulysses</Title> 
    <Author>James <b>Joyce</b></Author> 
</Book> 

ich diese mit Hilfe von Java in eine pojo wie

title="Ulysses" 
author="James <b>Joyce</b>" 

Mit anderen Worten analysieren müssen, ich brauche Die HTML- oder benutzerdefinierten benutzerdefinierten XML-Tags bleiben beim Analysieren als reine Textelemente und nicht als XML-Elemente erhalten.

Ich kann das XML überhaupt nicht bearbeiten, aber es wäre in Ordnung für mich, eine benutzerdefinierte xslt-Datei zu erstellen, um das XML zu transformieren.

ich die folgende Java-Code für die Verwendung von Xslt haben mit dem Lesen des XML zu unterstützen,

TransformerFactory factory = TransformerFactory.newInstance(); 
    Source stylesheetSource = new StreamSource(new File(stylesheetPathname).getAbsoluteFile()); 
    Transformer transformer = factory.newTransformer(stylesheetSource); 
    Source inputSource = new StreamSource(new File(inputPathname).getAbsoluteFile()); 
    Result outputResult = new StreamResult(new File(outputPathname).getAbsoluteFile()); 
    transformer.transform(inputSource, outputResult); 

Das ist mein Xslt in die Datei gilt, die aus geschrieben, aber ich kann nicht kommen mit dem richtigen xslt, um es zu tun. Ich habe mir Add CDATA to an xml file angesehen, aber das funktioniert nicht für mich.

Im Grunde glaube ich möchte, dass die Datei aussehen

<?xml version="1.0"?> 
<Book> 
    <Title>Ulysses</Title> 
    <Author><![CDATA[James <b>Joyce</b>]]></Author> 
</Book> 

Dann kann ich "James <b>Joyce</b>" extrahieren. Ich habe versucht, den hier vorgeschlagenen Ansatz: Add CDATA to an xml file Aber es hat nicht für mich funktioniert.

habe ich die folgende Xslt:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" indent="yes" omit-xml-declaration="no"/> 

<xsl:template match="Author"> 
<xsl:copy> 
<xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text> 
<xsl:copy-of select="*"/>  
<xsl:text disable-output-escaping="yes">]]&gt;</xsl:text> 
</xsl:copy> 
</xsl:template> 

und dies erzeugt:

<?xml version="1.0" encoding="UTF-8"?> 
    Ulysses 
    <Author><![CDATA[ 
<b>Joyce</b>]]></Author> 

Können Sie mir bitte dabei helfen? Ich möchte, dass das Originaldokument in seiner Gesamtheit ausgeschrieben wird, aber mit der CDATA, die alles innerhalb des Autorenelements umgibt. Dank

+1

Was bedeutet „es nicht für mich arbeiten“ aussehen? XML mit Markup ist kein richtiges XML. Sie können diesen magischen Zeichen entkommen oder in CDATA einhüllen. Keine andere Wahl. – duffymo

Antwort

0

Mit XSLT 3.0 als von Saxon 9.8 HE (auf Maven und Source) unterstützt werden, können Sie XSLT wie folgt verwenden:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:math="http://www.w3.org/2005/xpath-functions/math" 
    exclude-result-prefixes="xs math" 
    version="3.0"> 

    <xsl:output cdata-section-elements="Author"/> 

    <xsl:mode on-no-match="shallow-copy"/> 

    <xsl:template match="Author"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*"/> 
      <xsl:value-of select="serialize(node())"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

Was Ihre Versuch, Sie im Grunde zu „implementieren“ müssen die Identität Transformation Vorlage kurz in XSLT 3.0 als <xsl:mode on-no-match="shallow-copy"/> als Vorlage geschrieben

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

in XSLT 1.0, so dass diese Knoten nicht durch speziellere Templat behandelt (wie das für Author Element s) werden rekursiv kopiert.

Dann mit der Kopie-alle untergeordneten Knoten node() Auswahl und nicht nur die Elementknoten * Sie

<xsl:template match="Author"> 
<xsl:copy> 
<xsl:apply-templates select="@*"/> 
<xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text> 
<xsl:copy-of select="node()"/>  
<xsl:text disable-output-escaping="yes">]]&gt;</xsl:text> 
</xsl:copy> 
</xsl:template> 
+0

Ich habe Ihr XSLT 1.0 Beispiel versucht und es verhält sich jetzt wie erwartet, außer dass es einige Zeilenumbruchunterschiede gibt. Irgendwelche Ideen, wie man das anspricht? Ich habe versucht, die Eingabe/Ausgabe hier in diesem Kommentar hinzuzufügen, aber es wird nicht gut angezeigt. Vielen Dank für Ihre Antwort, ich schätze es sehr. –

+0

Erfolgt das mit oder ohne 'xsl: output'' indent = "yes" '? Ich würde versuchen, ohne Whitespace zu erhalten. –

+0

Ich habe versucht, sowohl den Einzug = "Nein" und entfernen es insgesamt, aber das Ergebnis war das gleiche. –

0

bekommen, ist keine einfachen HTML/XML-Parser wie Jsoup einen besseren Weg zur Lösung dieses mit ? Mit Jsoup können Sie so etwas wie dies versuchen:

import org.jsoup.Jsoup; 
import org.jsoup.nodes.Document; 
import org.jsoup.nodes.Element; 
import org.jsoup.parser.Parser; 
import org.jsoup.select.Elements; 

public class Example { 

    public static void main(String[] args) { 
     String xml = "<?xml version=\"1.0\"?>\n" 
       + "<Book>\n" 
       + " <Title>Ulysses</Title>\n" 
       + " <Author>James <b>Joyce</b></Author>\n" 
       + "</Book>"; 
     Document doc = Jsoup.parse(xml, "", Parser.xmlParser()); 
     doc.outputSettings().prettyPrint(false); 
     Elements books = doc.select("Book"); 
     for(Element e: books){ 
      Book b = new Book(e.select("Title").html(),e.select("Author").html()); 
      System.out.println(b.title); 
      System.out.println(b.author); 
     } 
    } 
    public static class Book{ 
     String title; 
     String author; 

     public Book(String title, String author) { 
      this.title = title; 
      this.author = author; 
     }   
    } 
} 
+0

Vielen Dank für Ihre Antwort. Dies erreicht, was ich in diesem Fall suche, aber wenn ich mehr html hinzufüge, wird es geändert, wenn es von Jsoup geparst wird, was ich für den genauen Text zwischen dem Element benötige, das reproduziert wird, ohne geändert zu werden. –