2008-11-26 64 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

相关问题