2017-10-11 65 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解析时会被更改,我需要的是元素之间的确切文本被重现而不被更改。 –

相关问题