2017-09-01 34 views
1

我有一個xml文檔(輸入文件無法更改),我需要用xsl轉換爲另一個xml。輸入XSL有CDATA如以下的示例結構:XSL:轉義CDATA並解析爲XML每個內部

<TestCaseElement> 
    <Role>VP</Role> 
    <Code> 
     <Line> 
      <![CDATA[<id>l1_SomeId1</id> <val1>l1_SomeVal1</val1> <val2>l1_SomeVal2</val2> <algo>l1_somealgo</algo>]]> 
     </Line> 
     <Line> 
      <![CDATA[<id>l2_someid1</id> <val1>l2_SomeVal1<val1> <val2>l2_SomeVal2<val2> <algo>l2_somealgo</algo>]]> 
     </Line> 
    </Code> 
<TestCaseElement> 

預期的結果是這樣的:

<Expected> 
    <MEASV id="l1_SomeId1" val1="l1_SomeVal1" val2="l1_SomeVal2" algo="l1_somealgo"> 
    <MEASV id="l2_SomeId1" val1="l2_SomeVal1" val2="l2_SomeVal2" algo="l2_somealgo"> 
</Expected> 

我的XSLT是這樣的:

<Expected> 
    <xsl:for-each select="TestCaseElement[(Role='VP')]/Code/Line">      
     <xsl:for-each select="current()/*"> 
      <MEASV> 
       <xsl:attribute name="{fn:local-name()}"><xsl:value-of select="current()"/></xsl:attribute> 
      </MEASV> 
     </xsl:for-each>          
    </xsl:for-each> 
</Expected> 

問題是xslt無法識別CDATA中的標籤。我如何爲每個應用一種禁用輸出轉義?或者任何其他方法來解決這個問題?

+0

哪個XSLT處理器將您使用? –

+0

處理器位於名爲「MBT套件」的程序中。但看看關於我的頁面,我發現它說「Saxon-HE 9.5.1」。我認爲這是XSLT處理器。 –

+0

檢查Saxon文檔以查看是否支持將字符串解析爲XML作爲擴展。否則,您需要兩次完成此操作,其中第一次執行DOE並將結果保存到文件中。 –

回答

0

考慮使用XSLT 3.0和parse-xml-fragment()(由撒克遜9.8和Altova的XMLSpy的/猛禽提供支援):

<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 indent="yes"/> 

    <xsl:template match="/"> 
     <Expected> 
      <xsl:apply-templates select="TestCaseElement[(Role = 'VP')]/Code/Line"/> 
     </Expected> 
    </xsl:template> 

    <xsl:template match="Line"> 
     <MEASV> 
      <xsl:apply-templates select="parse-xml-fragment(.)/*"/> 
     </MEASV> 
    </xsl:template> 

    <xsl:template match="*"> 
     <xsl:attribute name="{local-name()}" select="."/> 
    </xsl:template> 

</xsl:stylesheet> 

請注意,您發佈的樣品中一人逃脫標記<![CDATA[<id>l2_someid1</id> <val1>l2_SomeVal1<val1> <val2>l2_SomeVal2<val2> <algo>l2_somealgo</algo>]]>包含val1val2不是畸形的標記正確關閉,所以上面的代碼將無法爲輸入或你需要使用try/catch捕獲任何解析錯誤:

<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" 
    xmlns:err="http://www.w3.org/2005/xqt-errors" 
    exclude-result-prefixes="xs math err" 
    version="3.0"> 

    <xsl:output indent="yes"/> 

    <xsl:template match="/"> 
     <Expected> 
      <xsl:apply-templates select="TestCaseElement[(Role = 'VP')]/Code/Line"/> 
     </Expected> 
    </xsl:template> 

    <xsl:template match="Line"> 
     <MEASV> 
      <xsl:try> 
       <xsl:apply-templates select="parse-xml-fragment(.)/*"/> 
       <xsl:catch errors="err:FODC0006"> 
        <xsl:message select="'Error parsing', ."/> 
       </xsl:catch> 
      </xsl:try> 
     </MEASV> 
    </xsl:template> 

    <xsl:template match="*"> 
     <xsl:attribute name="{local-name()}" select="."/> 
    </xsl:template> 

</xsl:stylesheet> 
+0

非常感謝我會盡力實施這種方式。首先,我需要檢查我的處理器是否支持XML3.0。 –

+0

輸入錯誤你是對的,這只是一個例子,不是真正的輸入。還是謝謝! –

+0

我在XMLSpy中試過並且正在工作,非常感謝。不幸的是,我的處理器不允許XML3.0或任何擴展(甚至撒克遜),(它說它使用Saxon-HE 9.5.1,但我不確定)。我正在考慮製作一箇中間文件,也許這是有效的。 –