2012-05-31 31 views
2

我有一個xml文件,並且想要使用帶有複雜規則的xslt來轉換它。 源XML是這樣的:如何使用xslt和複雜規則來轉換xml

<analysis> 
    <blocks> 
     <block id="35" original="5,13"> 
      <contain>6 ,7</contain> 
     </block> 
     <block id="33" original="20"> 
      <contain>11, 8, 9, 10</contain> 
     </block> 
    </blocks> 
    <images> 
     <image id = "11">./img/a.jpg </image> 
    </images> 
    <lines> 
     <line id="6"/> 
      <char font="2">a</char> 
      <char font="2">a</char> 
      <char font="2">a</char> 
      <char font="2">a</char> 
     <line id="7"/> 
      <char font="2">b</char> 
      <char font="2">b</char> 
      <char font="2">b</char> 
      <char font="2">b</char> 
     <line id="8"/> 
      <char font="2">c</char> 
      <char font="2">c</char> 
      <char font="2">c</char> 
      <char font="2">c</char> 
     <line id="9"/> 
      <char font="2">d</char> 
      <char font="2">d</char> 
      <char font="2">d</char> 
      <char font="2">d</char> 
     <line id="10"/> 
      <char font="2">e</char> 
      <char font="2">e</char> 
      <char font="2">e</char> 
      <char font="2">e</char> 
    </lines> 
</analysis> 

結果XML是:

<result> 
    <block id="35"> 
     <text> 
      aaaabbbb 
     </text> 
    </block> 
    <block id="33"> 
     <text> 
      cccc 
     </text> 
     <image ref="./img/a.jpg"/> 
     <text> 
      ddddeeee 
     </text> 
    </block> 
</result> 

的規則是:在標籤「塊」,有 「含有」標誌,其內容是id所在的塊所引用的設置。

+0

我應該怎麼做xslt ... ??? – CodeBoy

+0

這是一個常見的任務。那麼你有什麼嘗試,你卡在哪裏? –

+0

我不知道如何使用id屬性作爲提示來查找所有內容 – CodeBoy

回答

1

問題中唯一沒有意義的部分是img如何在輸出中的兩個text元素之間結束。

這是一個XSLT 2.0示例。這不是確切的,但可能已經足夠接近您進行修改以實現您所需的功能。

XML輸入

<analysis> 
    <blocks> 
     <block id="35" original="5,13"> 
      <contain>6 ,7</contain> 
     </block> 
     <block id="33" original="20"> 
      <contain>11, 8, 9, 10</contain> 
     </block> 
    </blocks> 
    <images> 
     <image id = "11">./img/a.jpg </image> 
    </images> 
    <lines> 
     <line id="6"/> 
      <char font="2">a</char> 
      <char font="2">a</char> 
      <char font="2">a</char> 
      <char font="2">a</char> 
     <line id="7"/> 
      <char font="2">b</char> 
      <char font="2">b</char> 
      <char font="2">b</char> 
      <char font="2">b</char> 
     <line id="8"/> 
      <char font="2">c</char> 
      <char font="2">c</char> 
      <char font="2">c</char> 
      <char font="2">c</char> 
     <line id="9"/> 
      <char font="2">d</char> 
      <char font="2">d</char> 
      <char font="2">d</char> 
      <char font="2">d</char> 
     <line id="10"/> 
      <char font="2">e</char> 
      <char font="2">e</char> 
      <char font="2">e</char> 
      <char font="2">e</char> 
    </lines> 
</analysis> 

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

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

    <xsl:template match="/"> 
     <results> 
      <xsl:apply-templates select="analysis/blocks/block"/> 
     </results> 
    </xsl:template> 

    <xsl:template match="block"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*[not(name()='original')]"/> 
      <xsl:apply-templates select="/*/*/image[@id=tokenize(current()/contain,'\s*,\s*')]"/> 
      <text> 
       <xsl:apply-templates select="/*/*/line[@id=tokenize(current()/contain,'\s*,\s*')]/following-sibling::char[preceding-sibling::line[1][@id=tokenize(current()/contain,'\s*,\s*')]]/text()"/> 
      </text>   
     </xsl:copy>  
    </xsl:template> 

    <xsl:template match="image"> 
     <image ref="{normalize-space(.)}"/> 
    </xsl:template> 

</xsl:stylesheet> 

XML輸出

<results> 
    <block id="35"> 
     <text>aaaabbbb</text> 
    </block> 
    <block id="33"> 
     <image ref="./img/a.jpg"/> 
     <text>ccccddddeeee</text> 
    </block> 
</results> 
0

該樣式表...

<xsl:stylesheet 
    version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" > 
<xsl:output method="xml" indent="yes" encoding="utf-8" /> 
<xsl:strip-space elements="text"/> 
<xsl:key name="text-resource" match="line" use="normalize-space(@id)" /> 
<xsl:key name="image-resource" match="image" use="normalize-space(@id)" /> 

<xsl:template match="/"> 
<result> 
    <xsl:apply-templates select="analysis/blocks/block" /> 
</result> 
</xsl:template> 

<xsl:template match="block"> 
    <block id="{@id}"> 
    <xsl:variable name="block" select="." /> 

    <xsl:variable name="block-texts" as="xs:string+"> 
    <xsl:for-each select="tokenize(contain/text(),'\s?,\s?')" > 
    <xsl:variable name="id" select="." /> 
    <xsl:for-each select="$block" > 
     <xsl:sequence select="key('text-resource',$id)/following-sibling::char[preceding-sibling::line[1][@id=$id]]" /> 
    </xsl:for-each> 
    </xsl:for-each> 
    </xsl:variable> 

    <xsl:if test="count($block-texts) != 0" > 
    <text> 
    <xsl:for-each select="$block-texts" > 
    <xsl:value-of select="." /> 
    </xsl:for-each> 
    </text> 
    </xsl:if> 

    <xsl:for-each select="tokenize(contain/text(),'\s?,\s?')" > 
    <xsl:variable name="id" select="." /> 
    <xsl:for-each select="$block" > 
     <xsl:for-each select="key('image-resource',$id)" > 
     <image href="{.}" /> 
     </xsl:for-each> 
     </xsl:for-each> 
    </xsl:for-each> 
    </block> 
</xsl:template> 

</xsl:stylesheet> 

...當應用到的問題,產量給出的輸入文檔...

<?xml version="1.0" encoding="utf-8"?> 
<result xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <block id="35"> 
     <text>aaaabbbb</text> 
    </block> 
    <block id="33"> 
     <text>ccccddddeeee</text> 
     <image href="./img/a.jpg "/> 
    </block> 
</result> 

我希望你找到我的最接近的解決方案。