2008-11-26 70 views
2

短版:LINQ或XSLT把一個元素到另一個在Visual Basic 9

任何人都可以建議或LINQ to XML中的VB提供的樣品,或在如何一個XML元素來改變成另一種的XSLT (沒有硬編碼所有未改變的元素的逐元素拷貝)?

背景:

我有一個XML文件,我認爲適當地形成,包含根條目是<collection>和多個<dvd>元素。在DVD中,有流派和標籤,如下所示。 (爲了簡單起見,我剪掉了很多其他元素)。

我想要做的就是將任何可能存在的元素轉換爲另一個<Genre>。例如,在下面的條目,我需要添加<Genre>兒童</Genre>。 (我知道這實際上是我期待變成體裁元素的標記元素的name屬性,但如果我甚至可以弄清楚如何創建一個名爲新流派「標籤」,我會提前更遠並且也許可以解出休息。)

我從來沒有做過任何與很多XML。我的理解是,我可以使用XSLT轉換文件和XSLCompiledTransform或者我可以使用LINQ到XML(我有Visual Basic 9,寧可做VB的所有內部)。 [我敢肯定有一些其他的辦法了。]

麻煩的是,我無法找到告訴我怎麼把一個元素到另一個XSLT或LINQ語法中的任何實例。我可以寫出足夠多的LINQ來逐個拷貝所有的元素,但是與對不變的所有元素的拷貝進行硬編碼相比,這需要更簡單的方法! (有一定是!)

因此,如果有人誰知道會指出我的例子或者給我拿一點的LINQ或XSLT啓動代碼,我將永遠感激(好吧,也許不是永遠,但至少很長一段時間!)。

謝謝。

示例XML:

<Collection> 
    <DVD> 
    <ID>0000502461</ID> 
    <Title>Cirque du Soleil: Alegría</Title> 
    <Released>2002-05-31</Released> 
    <RunningTime>90</RunningTime> 
    <Genres> 
     <Genre>Family</Genre> 
     <Genre>Music</Genre> 
    </Genres> 
    <Overview>What if anything were possible? What if ... 
    </Overview> 
    <Notes/> 
    <Tags> 
     <Tag Name="Kids" FullName="Kids"/> 
    </Tags> 
    </DVD> 
</Collection> 

回答

0

您正在尋找這樣的事情:

<xsl:template match="Tag"> 
    <xsl:element name="Genre"> 
     <xsl:value-of select="@Name"/>   
    </xsl:element>  
    </xsl:template> 
1

您可以node()任一節點,是這樣的:使用一個

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<!-- Uncomment to remove Tags elements --> 
<!-- <xsl:template match="Tags" /> --> 

<xsl:template match="Genres"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()" /> 
     <xsl:for-each select="../Tags/Tag"> 
      <xsl:element name="Genre"> 
       <xsl:value-of select="@Name" /> 
      </xsl:element> 
     </xsl:for-each> 
    </xsl:copy> 
</xsl:template> 

<!-- Default rule: Copy node and descend --> 
<xsl:template match="@*|node()"> 
     <xsl:copy> 
       <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 
2

最基本和最強大的XSLT設計模式:覆蓋identity template,on È將寫這個非常簡單的變換來替換每一個「流派」元素具有「主題」元素:

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

<xsl:output omit-xml-declaration="yes"/> 

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

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

當對所提供的源XML文檔應用:

 
<Collection> 
    <DVD> 
     <ID>0000502461</ID> 
     <Title>Cirque du Soleil: Alegría</Title> 
     <Released>2002-05-31</Released> 
     <RunningTime>90</RunningTime> 
     <Genres> 
      <Genre>Family</Genre> 
      <Genre>Music</Genre> 
     </Genres> 
     <Overview>What if anything were possible? What if ... </Overview> 
     <Notes/> 
     <Tags> 
      <Tag Name="Kids" FullName="Kids"/> 
     </Tags> 
    </DVD> 
</Collection> 

的想要的結果是產生的:

 
<Collection> 
    <DVD> 
     <ID>0000502461</ID> 
     <Title>Cirque du Soleil: Alegría</Title> 
     <Released>2002-05-31</Released> 
     <RunningTime>90</RunningTime> 
     <Topics> 
      <Genre>Family</Genre> 
      <Genre>Music</Genre> 
     </Topics> 
     <Overview>What if anything were possible? What if ... </Overview> 
     <Notes/> 
     <Tags> 
      <Tag Name="Kids" FullName="Kids"/> 
     </Tags> 
    </DVD> 
</Collection> 

樣式表中的第一個模板是標識規則。它不改變任何匹配的節點,遞歸地將模板應用於其屬性或子節點。如果沒有其他模板存在,則此模板創建相同的源xml文檔副本,因此它的名稱。

當存在更具體的模板(指定匹配節點的更多具體細節,如名稱和/或其他條件)時,它被稱爲「覆蓋」更通用的模板。這意味着選擇更具體的模板來處理節點。

使用這種極其強大的設計模式,它是瑣細的implementin短短的幾行這樣的處理爲:

  1. 刪除滿足某個條件的所有節點。
  2. 重命名滿足某些條件的所有節點。
  3. 修改滿足某個條件的

而拷貝的所有其他節點的完整的所有節點中的內容。

在我們的例子中,第二個模板更具體,它被選中用於處​​理名爲「流派」的每個元素。它所做的只是創建一個名爲「Topics」的元素,並在其中爲所有當前節點屬性和子級應用模板。

最後以下改造將增加一個新的「流派」元素「流派」的孩子,對每一個「標籤」元素

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

<xsl:output omit-xml-declaration="yes"/> 

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

    <xsl:template match="Genres"> 
     <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
     <xsl:apply-templates select="../Tags/Tag" mode="Gen"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Tag" mode="Gen"> 
     <Genre> 
     <xsl:value-of select="@Name"/> 
     </Genre> 
    </xsl:template> 
</xsl:stylesheet> 

結果又是必需的:

 
<Collection> 
    <DVD> 
     <ID>0000502461</ID> 
     <Title>Cirque du Soleil: Alegría</Title> 
     <Released>2002-05-31</Released> 
     <RunningTime>90</RunningTime> 
     <Genres> 
      <Genre>Family</Genre> 
      <Genre>Music</Genre> 
 <Genre>Kids</Genre> 
 
     </Genres> 
     <Overview>What if anything were possible? What if ... </Overview> 
     <Notes/> 
     <Tags> 
      <Tag Name="Kids" FullName="Kids"/> 
     </Tags> 
    </DVD> 
</Collection> 

使用「身份規則」模式的更多代碼片段可以找到here

+0

不錯的解釋,但第二個樣式表規則和結果(沒有區別輸入?!)似乎是錯誤 – phihag 2008-11-27 00:35:09

相關問題