2012-06-27 77 views
1

我需要採用「a」標籤的屬性並處理它們。處理屬性並根據字符串拆分它們

來源:

<Data> 
    <AAA> 
    <strong xmlns="http://www.w3.org/1999/xhtml">some Text 
    <a href="#" name="Value1,Value2,Value3,Value4,Value5,Value6" id="Functionaldata" xmlns="http://www.w3.org/1999/xhtml">Value6</a> 
    </strong> 
    hello 
    <a title="google" href="http://google.com" xmlns="http://www.w3.org/1999/xhtml">Hey</a> all <a href="#" name="element1,element2,element3,element4,element5,element6" id="Functionaldata" xmlns="http://www.w3.org/1999/xhtml">element6</a> 
    <AAA> 
</Data> 

輸出

<Content> 
    <Information> 
    <text> 
     <strong xmlns="http://www.w3.org/1999/xhtml">some Text 
     <dynamicinfo type="Value1" name="Value2" group="Value3" id="Value4" link="Value5" display="Value6"/> 
    </strong> 
    hello<a title="google" href="http://google.com">Hey</a> all 
    <dynamicinfo type="element1" name="element2" group="element3" id="element4" link="element5" display="element6"/> 
    </text> 
    </Information> 
</Content> 

我在處理 「一個」 標籤使用id = Functionaldata我感到震驚。

任何可以幫助他們對它的看法。

謝謝。

+0

用戶222:是我的回答對你有用嗎,你仍然有任何問題? –

+0

@DimitreNovatchev。這對我很有用。謝謝 – Patan

+0

用戶222:不客氣。 –

回答

1

這種轉變

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:x="http://www.w3.org/1999/xhtml" 
    xmlns:my="my:my"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <my:names> 
     <n>type</n> 
     <n>name</n> 
     <n>group</n> 
     <n>id</n> 
     <n>link</n> 
     <n>display</n> 
    </my:names> 

    <xsl:variable name="vNames" select="document('')/*/my:names/*"/> 

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

     <xsl:template match="a[@name] | x:a[@name]"> 
      <xsl:copy> 
      <xsl:apply-templates select="@*[not(name()='name')]"/> 
      <xsl:apply-templates select="@name"/> 
      </xsl:copy> 
     </xsl:template> 

    <xsl:template match="a/@name | x:a/@name" name="split"> 
     <xsl:param name="pText" select="."/> 
     <xsl:param name="pOrd" select="1"/> 

     <xsl:if test="$pText"> 
     <xsl:attribute name="{$vNames[position()=$pOrd]}"> 
      <xsl:value-of select= 
      "substring-before(concat($pText, ','), ',')"/> 
     </xsl:attribute> 

     <xsl:call-template name="split"> 
      <xsl:with-param name="pText" select="substring-after($pText, ',')"/> 
      <xsl:with-param name="pOrd" select="$pOrd+1"/> 
     </xsl:call-template> 
     </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

時所提供的XML文檔應用:

<Data> 
     <AAA> 
     <strong xmlns="http://www.w3.org/1999/xhtml">some Text 
     <a href="#" name="Value1,Value2,Value3,Value4,Value5,Value6" id="Functionaldata">Value6</a> 
     </strong> 
     hello 
     <a title="google" href="http://google.com">Hey</a> all 
     <a href="#" name="element1,element2,element3,element4,element5,element6" id="Functionaldata">element6</a> 
     </AAA> 
</Data> 

產生想要的,正確的結果:

<Data> 
    <AAA> 
     <strong xmlns="http://www.w3.org/1999/xhtml">some Text 
     <a href="#" id="Value4" type="Value1" name="Value2" group="Value3" link="Value5" display="Value6"/> 
     </strong> 
     hello 
     <a title="google" href="http://google.com">Hey</a> all 
     <a href="#" id="element4" type="element1" name="element2" group="element3" link="element5" display="element6"/> 
    </AAA> 
</Data> 

說明

這是建立在你以前的問題的解決,有以下變化:

  1. 使用和身份規則的重寫。

  2. 而不是元素,創建具有作爲值分裂的結果的屬性。

  3. 要生成的屬性的名稱被指定爲全局my:names元素的子項。

UPDATE

在評論中OP已經修改了他的問題,他說:

我忘了添加名字空間 「一」 的標籤。所有「a」標籤都有 「xhtml」命名空間。

答案是,在這種情況下,提供的轉換工作仍然可以,並且不需要改變。

然而,可以可以通過以下方式簡化:

更換

<xsl:template match="a[@name] | x:a[@name]"> 

只有

<xsl:template match="x:a[@name]"> 

和替換

<xsl:template match="a/@name | x:a/@name" name="split"> 

只有

<xsl:template match="x:a/@name" name="split"> 

這些更改後的徹底改造就變成了:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:x="http://www.w3.org/1999/xhtml" 
    xmlns:my="my:my"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <my:names> 
     <n>type</n> 
     <n>name</n> 
     <n>group</n> 
     <n>id</n> 
     <n>link</n> 
     <n>display</n> 
    </my:names> 

    <xsl:variable name="vNames" select="document('')/*/my:names/*"/> 

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

     <xsl:template match="x:a[@name]"> 
      <xsl:copy> 
      <xsl:apply-templates select="@*[not(name()='name')]"/> 
      <xsl:apply-templates select="@name"/> 
      </xsl:copy> 
     </xsl:template> 

    <xsl:template match="x:a/@name" name="split"> 
     <xsl:param name="pText" select="."/> 
     <xsl:param name="pOrd" select="1"/> 

     <xsl:if test="$pText"> 
     <xsl:attribute name="{$vNames[position()=$pOrd]}"> 
      <xsl:value-of select= 
      "substring-before(concat($pText, ','), ',')"/> 
     </xsl:attribute> 

     <xsl:call-template name="split"> 
      <xsl:with-param name="pText" select="substring-after($pText, ',')"/> 
      <xsl:with-param name="pOrd" select="$pOrd+1"/> 
     </xsl:call-template> 
     </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 
+0

謝謝你的回答。有一點疑問,我忘了爲「a」標籤添加名稱空間。所有的「a」標籤都有「xhtml」命名空間。那麼代碼中會有什麼變化。 – Patan

+0

@ User222:如果所有'a'元素都屬於xhtml命名空間,則不需要更改轉換。它*可以被簡化,以便匹配模式'a/@ name | x:a/@ name'就變成了'x:a/@ name'。請編輯該問題,以便源XML文檔中的所有'a'元素確實位於xhtml命名空間中,以便讀者不會感到困惑。 –

+0

@ User222:查看我的答案更新。 –

0

如果您有權訪問EXSLT,則可以使用str:split()方法來實現此目的。

更大的問題是,您如何將值映射到您賦予它們的新屬性名稱?我想出了這一點,這宣告值名稱前期然後值名稱1映射到拆分值1,值名稱2分值2等

<!-- node-set of value names, which will each correspond to the value at the same index, once they're split --> 
<xsl:variable name='value_names' select='str:split("type|name|group|id|link|display", "|")' /> 

<!-- match root --> 
<xsl:template match="/"> 
    <dynamicdata> 
     <xsl:apply-templates name='values' select='str:split(root/a/@name, ",")' /> 
    </dynamicdata> 
</xsl:template> 

<!-- iteration content - each value from the split --> 
<xsl:template match='token'> 
    <xsl:variable name='pos' select='position()' /> 
    <xsl:attribute name='{$value_names[$pos]}'><xsl:value-of select='.' /></xsl:attribute> 
</xsl:template> 

您可以在this XMLPlayground session行動中看到這個(見輸出源)。