gpt4 book ai didi

xml - 在 Visual Basic 9 中将一个元素转换为另一个元素的 LINQ 或 XSLT

转载 作者:行者123 更新时间:2023-12-04 07:11:05 25 4
gpt4 key购买 nike

精简版:

任何人都可以在 LINQ to XML for VB 或 XSLT 中建议或提供一个示例,说明如何将一个 XML 元素更改为另一个(无需硬编码所有未更改元素的逐个元素副本)?

背景:

我有一个我认为格式正确的 XML 文件,其中包含一个根条目 <collection > 和多个 <dvd > 元素。在 DVD 中,有流派和标签,如下所示。 (为简单起见,我删除了许多其他元素)。

我想做的是转任何<Tag > 可能存在于附加 <Genre 中的元素>.例如,在下面的条目中,我需要添加 <Genre > child </Genre >. (我意识到实际上是 TAG 元素的 NAME 属性,我希望将其转换为 GENRE 元素,但如果我什至能弄清楚如何创建一个名为“Tag”的新 GENRE,我会走得更远并且可能会弄清楚其余的。)

我从来没有对 XML 做过任何事情。我的理解是我可以使用 XSLT 转换文件和 XSLCompiledTransform 或者我可以使用 LINQ to 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>

最佳答案

使用最基本和最强大的 XSLT 设计模式之一:覆盖 identity template ,人们将编写这个非常简单的转换来用“主题”元素替换每个“流派”元素:

<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>

When applied against the provided source XML document:

<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>

The wanted result is produced:

<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>

The first template in the stylesheet is the identity rule. It copies any matched node unchanged and recursively applies templates to its attributes or children. If no other template is present, this template creates identical copy of the source xml document, hence its name.

When there is a more specific template (specifying more specific details for the matched node, such as name and/or other conditions), it is said to "override" the more generic templates. This means that the more specific template is chosen for processing the node.

Using this extremely powerful design pattern it is trivial to implementin just a few lines such processing as:

  1. Delete all nodes that satisfy some condition.
  2. Rename all nodes that satisfy some condition.
  3. Modify the contents of all nodes that satisfy some condition

while copying all other nodes intact.

In our case, the second template is more specific and it gets selected for processing of every element named "Genres". All it does is create an element named "Topics" and inside it apply templates to all of the current node attributes and children.

Finally, the following transformation will add a new "Genre" element to the children of "Genres", for each "Tag" element:

<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>

The result is again as required:

<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>


<概述>如果一切皆有可能呢?如果...
<注意事项/>
<标签>





可以找到更多使用“身份规则”模式的代码片段 here .

关于xml - 在 Visual Basic 9 中将一个元素转换为另一个元素的 LINQ 或 XSLT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/322496/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com