2011-05-14 43 views
6

這是我的XML的一部分:使用XPath和VTD-XML獲得子節點和元素的文本字符串

<MAIN> 
    <L> 
     <D>string1 string2 <b>string3</b> string4</D> 
    </L> 
    <L> 
     <D>string5 string6 <b>string7</b> string8 <i>string9</i></D> 
    </L> 
</MAIN> 

I want to get the content of all the <D> tags as string. So, the example above should return: 

1st iteration: 'string1 string2 <b>string3</b> string4' 
2nd iteration: 'string5 string6 <b>string7</b> string8 <i>string9</i>' 
etc... 

在VTD-XML的我用了一個自動駕駛儀的XPath「//大號/ D「和」// L/D/text()「,但沒有奏效。

任何意見或替代方法將不勝感激。

問候

+0

難道你不能只使用// L將返回一個節點列表。然後,對於那些節點循環直接的孩子,並調用任何方法返回文本。 – gshauger 2011-05-14 20:15:22

+0

好問題,+1。查看我的答案,獲取完整而簡短的XPath表達式解決方案。 – 2011-05-15 16:46:50

回答

12

下面是已經做了你在找什麼的代碼。

VTDGen vg = new VTDGen(); 
    if (vg.parseFile("c://xml//alex.txt", true)){ 
     VTDNav vn = vg.getNav(); 
     AutoPilot ap = new AutoPilot(vn); 
     ap.selectXPath("//L/D"); 
     int i=-1; 
     while((i=ap.evalXPath())!=-1){ 
      long l = vn.getContentFragment(); 
      System.out.println(" -==> "+ vn.toString((int)l, (int)(l>>32))); 
     } 
    } 
+0

非常感謝!這解決了我的問題。 – Alex 2011-05-17 21:44:30

+0

@alex,你好! – 2011-05-20 09:43:24

+0

我開始使用這種方法,但它似乎破壞逃逸的字符。例如,如果內容有'&',打印的字符串只有「&」。我遇到了這個問題,並將其作爲單獨的問題發佈[這裏](http://stackoverflow.com/questions/27823107/vtd-xml-seems-to-be-spoiling-escaped-string-in-xml -文件)。 – 2015-01-07 16:07:21

3

使用

/*/L/D/node() 

這裏選擇任何D元素是一個孩子的孩子的所有節點(元素,文本節點,處理的指令和註釋節點)任何L元素是XML文檔頂部元素的子元素。

或者,你可以分別選擇兩個/*/L/D元素的所有節點的孩子:

/*/L[1]/D/node() 

/*/L[2]/D/node() 

驗證使用XSLT作爲XPath的的主機:

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

<xsl:template match="/"> 
    <xsl:copy-of select="/*/L[1]/D/node()"/> 
-------------------- 
    <xsl:copy-of select="/*/L[2]/D/node()"/> 
</xsl:template> 
</xsl:stylesheet> 

時所提供的XML文檔應用:

<MAIN> 
    <L> 
     <D>string1 string2 
      <b>string3</b> string4 
     </D> 
    </L> 
    <L> 
     <D>string5 string6 
      <b>string7</b> string8 
      <i>string9</i> 
     </D> 
    </L> 
</MAIN> 

想要的,正確的結果產生

string1 string2 
      <b>string3</b> string4 

-------------------- 
    string5 string6 
      <b>string7</b> string8 
      <i>string9</i> 
+0

感謝您的回覆。這沒有奏效。它遍歷D標籤內的節點,因此在第一個D標籤上它會轉到b標籤,在第二個D標籤上它首先轉到b標籤,然後轉到i標籤。 – Alex 2011-05-15 17:41:57

+0

@Alex:如果是這種情況,那麼您沒有使用符合XPath的實現 - 節點測試node()必須選擇當前節點的所有子節點 - 不僅是元素。我懷疑當正確的操作是檢查所有選定的節點時,您只檢查生成的節點列表中的元素。 – 2011-05-15 17:49:31

+0

@alex,是否是vtd-xml的錯誤? – 2011-05-16 02:10:35

相關問題