通过XSL将XML导入Access,父笔记重复子节点

时间:2014-11-19 05:46:29

标签: xml ms-access xslt

我正在尝试使用XSL转换将属性中心XML文件导入Access。需要发生的事情就是转换它(伪装成不违反公司政策):

<PLANETARY Protocol="Solar 1">
  <COLONIES>
        <COLONYDATA site="10001" planet="Mars">
            <RESOURCEDATA resource="RadiationDanger" value="Low" />
            <RESOURCEDATA resource="ApplicantColonists" value="11" />
            <RESOURCEDATA resource="AcceptedColonists" value="3" />
        </COLONYDATA>
        <COLONYDATA site="10002" planet="Mars">
            <RESOURCEDATA resource="RadiationDanger" value="Low" />
            <RESOURCEDATA resource="ApplicantColonists" value="7" />
            <RESOURCEDATA resource="AcceptedColonists" value="1" />
        </COLONYDATA>
    </COLONIES>
  </PLANETARY>

进入这个:

<Protocol>
    <COLONIES>
        <COLONYDATA>
            <protocol>10002</protocol>
            <site>10001</site>
            <planet>Mars</planet>
            <RadiationDanger>Low</RadiationDanger>
            <ApplicantColonists>11</ApplicantColonists>
            <AcceptedColonists>3</AcceptedColonists>
        </COLONYDATA>
        <COLONYDATA>
            <protocol>10002</protocol>
            <site>10002</site>
            <planet>Mars</planet>
            <RadiationDanger>Low</RadiationDanger>
            <ApplicantColonists>7</ApplicantColonists>
            <AcceptedColonists>1</AcceptedColonists>
        </COLONYDATA>
    </COLONIES>
</Protocol>

最终我真正需要的是Access中的表看起来像这样,将XML转换为上面的内容可能是也可能不是最佳路径,但确实有效:

protocol    site    planet  RadiationDanger ApplicantColonists  AcceptedColonists
Solar1      10001   Mars    Low             11                  3
Solar1      10002   Mars    Low             7                   1

圣徒Lingamurthy给了我以下代码,除了让父节点与子节点一起重复之外,它做了所有事情(主要是因为我当时不知道我需要它):

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

<xsl:template match="@*" >
    <xsl:element name="{name()}">
        <xsl:value-of select="."/>
    </xsl:element>
</xsl:template>

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

<xsl:template match="/PLANETARY">
    <Protocol>
        <xsl:value-of select="@Protocol"/>
        <xsl:apply-templates select="node()"/>
    </Protocol>
</xsl:template>

<xsl:template match="RESOURCEDATA">
    <xsl:element name="{@resource}">
        <xsl:value-of select="@value"/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

如果可能的话,我想了解这是如何运作的。我不得不承认,在这一点上,XSLT对我来说并没有多大意义。它比VBA更抽象,我已经非常熟悉了。但我对任何可以让它发挥作用的建议感到满意。谢谢!

1 个答案:

答案 0 :(得分:2)

我不太确定,但我想你希望每个PLANETARY/@Protocol中的COLONYDATA而不是site的值。你想要另一个输出(如表)?您想使用HTML代码在浏览器上显示还是希望它是纯文本?

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

<xsl:variable name="Protocol" select="/PLANETARY/@Protocol"/>

<xsl:template match="@*" >
    <xsl:element name="{name()}">
        <xsl:value-of select="."/>
    </xsl:element>
</xsl:template>

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

<xsl:template match="/PLANETARY">
    <Protocol>
        <xsl:apply-templates select="node()"/>
    </Protocol>
</xsl:template>

<xsl:template match="RESOURCEDATA">
    <xsl:element name="{@resource}">
        <xsl:value-of select="@value"/>
    </xsl:element>
</xsl:template>

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

</xsl:stylesheet>