2010-06-09 34 views
2

鑑於這種XML ...如何使用沒有空白和標籤編碼的XSLT將節點集複製到結果屬性中?

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <item> 
     <this> 
<that>one</that> 
     </this> 
    </item> 
    <item> 
     <this> 
<that>two</that> 
     </this> 
    </item> 
    <item> 
     <this> 
<that>three</that> 
     </this> 
    </item> 
</root> 

我想要做的項目複製到一個新的格式,它看起來像......

<new> 
    <parm x="&gt;that&lt;one&gt;/that&lt;"/> 
    <parm x="&gt;that&lt;two&gt;/that&lt;"/> 
    <parm x="&gt;that&lt;three&gt;/that&lt;"/> 
</new> 

樣式表...

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:param name="feedKey"/> 

    <xsl:template match="/"> 
     <new> 
      <xsl:apply-templates select="//item"/> 
     </new> 
    </xsl:template> 

    <xsl:template match="item"> 
     <xsl:element name="param"> 
      <xsl:attribute name="x"><xsl:copy-of select="node()"/></xsl:attribute> 
     </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

...產生...

<?xml version="1.0" encoding="UTF-8"?> 
<new> 
    <param x="&#xA;  &#xA;one&#xA;  &#xA; "/> 
    <param x="&#xA;  &#xA;two&#xA;  &#xA; "/> 
    <param x="&#xA;  &#xA;three&#xA;  &#xA; "/> 
</new> 

簡單地更改紙張要移除的屬性...

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:param name="feedKey"/> 

    <xsl:template match="/"> 
     <new> 
      <xsl:apply-templates select="//item"/> 
     </new> 
    </xsl:template> 

    <xsl:template match="item"> 
     <xsl:element name="param"> 
      <xsl:copy-of select="node()"/> 
     </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

... ...產生

<?xml version="1.0" encoding="UTF-8"?> 
<new> 
    <param> 
     <this> 
     <that>one</that> 
     </this> 
    </param> 
    <param> 
     <this> 
     <that>two</that> 
     </this> 
    </param> 
    <param> 
     <this> 
     <that>three</that> 
     </this> 
    </param> 
</new> 

我怎麼能轉換「這個」入屬性「X」與空白區域被剝離並且標籤被編碼?

+0

好問題(+1)。見我的回答對一個完整的解決方案。 :) – 2010-06-09 19:35:32

回答

0

據我所知,如果我正確理解你的問題; XSLT中沒有這樣做的方法。我的假設是W3C考慮將轉義的XML存儲爲反模式。我的方法是定義一個命名模板:

<xsl:template name='recursive_escape'> 
<xsl:text>;&lt;</xsl:text> 
<xsl:value-of select='local-name()'/> 
<xsl:for-each select='child::attribute()'> 
<xsl:value-of select='local-name()'/> 
<xsl:text>='</xsl:text><xsl:value-of select='.'/><xsl:text>'</xsl:text> 
</xsl:for-each> 
<xsl:text>/;&gt;</xsl:text>.... 

依此類推。我希望你可以解釋我在這裏要做的事情:手動構建一個帶有上下文節點名稱和每個屬性名稱和值的開始標記,然後遍歷上下文節點的每個子節點並調用相同的模板再次;等等。我沒有我的原始實現,所以毫無疑問,我的例子有一些錯誤;這只是一個指導。

如果有人知道更好的方法,我想聽聽它;它可能在尚未正式確定的XSLT 2.0中,IIRC。爲了提高健壯性和支持MSXML,它必須是XSLT 1.0。

2

這種變換:

<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="/"> 
    <new> 
    <xsl:apply-templates select="*/*/this/*"/> 
    </new> 
</xsl:template> 

<xsl:template match="*"> 
    <xsl:variable name="vStr"> 
    <xsl:text>&lt;</xsl:text> 
    <xsl:value-of select="name()"/> 
    <xsl:text>&gt;</xsl:text> 

    <xsl:apply-templates/> 

    <xsl:text>&lt;/</xsl:text> 
    <xsl:value-of select="name()"/> 
    <xsl:text>&gt;</xsl:text> 
    </xsl:variable> 

    <parm x="{$vStr}"/> 
</xsl:template> 
</xsl:stylesheet> 

當所提供的XML文檔施加:

<root> 
    <item> 
     <this> 
      <that>one</that> 
     </this> 
    </item> 
    <item> 
     <this> 
      <that>two</that> 
     </this> 
    </item> 
    <item> 
     <this> 
      <that>three</that> 
     </this> 
    </item> 
</root> 

生成所需的結果

<new> 
    <parm x="&lt;that&gt;one&lt;/that&gt;"/> 
    <parm x="&lt;that&gt;two&lt;/that&gt;"/> 
    <parm x="&lt;that&gt;three&lt;/that&gt;"/> 
</new> 
相關問題