2017-02-20 65 views
1

我嘗試使用XSLT將Doxygen XML轉換爲文本輸出。 Doxygen的返回此XML結構:XSLT:選擇沒有子樹的所有元素

<detaileddescription> 
    <para>a long text with <formula id="6">$ \LaTeX $</formula> code</para> 
    <para> 
     <simplesect kind="see"> 
      <para> 
       <ulink url="url">url description</ulink> 
      </para> 
     </simplesect> 
    </para>  
</detaileddescription> 

我儘量只選擇不包含simplesect節點或任何其他「複雜的樹狀結構」是para節點。
我試試這個XPath:

detaileddescription/para/node() 

但是這也將返回simplesect/para節點。
那麼,如何才能選擇僅包含text()節點和formula節點作爲兄弟節點的para節點?

+1

要選擇不包含'simplesect'的'para',可以使用'/ detaileddescription/para [not(simplesect)]'。我不確定你的意思是「*其他任何」複雜的樹形結構「*」 –

+0

你真的想要選擇什麼'para'節點/元素? – zx485

回答

0

的XPath來僅獲取ulink節點將是

//para[count(descendant::*) &lt; 2 and count(text()) = 0] 

全XSLT-1.0實現這一目標是

<?xml version="1.0" ?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" /> 

    <xsl:template match="text()" /> 

    <xsl:template match="//para[count(descendant::*) &lt; 2 and count(text()) = 0]"> 
    <xsl:copy-of select="." /> 
    </xsl:template> 

</xsl:stylesheet> 

其輸出是

<?xml version="1.0"?> 
<para> 
    <ulink url="url">url description</ulink> 
</para> 
+0

感謝幫助了很多,我使用的匹配表達式: '第[計數(後裔:: *)> 0和計數(文本())> 0]' ,因爲我想獲得該節點 '帶有<公式編號=「6」>的長文本$ \ LaTeX $代碼' 因此,我總是需要一個文本節點,如果存在公式節點。 – Phil

+1

@Phil請在問題中顯示完整的XSLT樣式表,以及您期望的文本輸出。謝謝。 –

1

表達detaileddescription/para/node()不選擇simplesect/para節點。它選擇simplesect元素,但不選擇其子元素。我覺得你的困惑是關於發生了什麼你選擇了一個節點。您沒有向我們展示您如何處理選定的節點,但是例如,如果您將xsl:copy-of指令應用於選定的節點,則該指令不僅會複製選定的節點,還會複製其所有子節點和子節點。

如果您希望某個節點出現在輸出中,而其子節點也不會出現,那麼選擇該節點還不夠,您需要對其進行轉換(具體來說,創建排除其子節點的節點副本)。

0

你寫了para節點不包含...任何...複雜的樹結構

然後做你寫道:

  • 寫模板匹配para
  • 閱讀(直接)子文本節點,但只包含「真實」文本 (非空文本)。
  • 然後檢查你是否真的有東西。
  • 如果是(您的para包含一些非空文本(忘記 「深層」位於文本節點)),請執行標識轉換。
  • 否則您的para將不會呈現。

下面你有一個完整的解決方案。我添加了strip-space以避免空行輸出。

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes" /> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="para"> 
    <xsl:variable name="txt" select="text()[normalize-space()]"/> 
    <xsl:if test="$txt"> 
     <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy> 
    </xsl:if> 
    </xsl:template> 

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