2017-10-11 124 views
-1

我有一個XML文件中像下面解析XML:需要與HTML元素

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

我需要使用Java這個解析成一個POJO像

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

換句話說,我需要在解析時,html或可能的自定義xml標記保持爲純文本而不是xml元素。

我根本無法編輯XML,但可以創建自定義xslt文件來轉換xml。

我已經得到了使用XSLT協助的XML閱讀下面的Java代碼,

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); 

這不我的XSLT適用於被寫入了文件,但我不能拿出用正確的xslt來做到這一點。我看了一下Add CDATA to an xml file,但這對我不起作用。

從本質上講,我相信我想要的文件看起來像

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

然後我可以提取 "James <b>Joyce</b>"。我嘗試了這裏建議的方法:Add CDATA to an xml file 但它沒有爲我工作。

我用下面的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> 

,並由此產生:

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

可以請你幫助呢?我想要將原始文檔全部寫出來,但是CDATA包含作者元素中的所有內容。 感謝

+1

什麼是「它沒有爲我工作」是什麼樣子?帶有標記的XML不是正確的XML。你可以逃脫那些魔法角色或者包裝在CDATA中。沒有其他選擇。 – duffymo

回答

0

使用XSLT 3.0由撒克遜9.8 HE所支持的(適用於Maven和Sourceforge上),你可以使用XSLT如下:

<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> 

至於你嘗試,你基本上需要「落實」身份簡明地寫在XSLT 3.0作爲<xsl:mode on-no-match="shallow-copy"/>作爲模板變換模板

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

以便這些節點沒有被更專門的模板處理(如一個用於Author元件s)通過遞歸複製。

然後,在選擇所有子節點node()不僅*

<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

我試過了你的XSLT 1.0例子,它現在的行爲和預期一樣,除了有一些換行符的區別。關於如何解決這個問題的任何想法?我試圖在這個評論中添加輸入/輸出,但它不能很好地顯示。 非常感謝您的回覆,我真的很感激。 –

+0

這是否發生有或沒有'xsl:output'' indent =「yes」'?如果空白應該保留,我會嘗試。 –

+0

我試着同時設置indent =「no」並完全刪除它,但結果是一樣的。 –

0

元素節點沒有使用像Jsoup一個簡單的HTML/XML解析器解決這個更好的方法複製的? 使用Jsoup你可以嘗試這樣的事:

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

謝謝你的迴應。這確實實現了我在這種情況下尋找的東西,但是如果我添加更多的html,它在被Jsoup解析時會被更改,我需要的是元素之間的確切文本被重現而不被更改。 –