我尝试使用XSLT 1.0转换节点,将其转换为新节点,然后使用其中一个属性作为其值,但它正在创建多个节点而不是覆盖一个并创建一个额外的节点,我该如何解决这个问题?
以下是数据的示例部分,其中我感兴趣的节点是' unitid'。应将此节点的值复制到新节点,< physloc'和' unitid'价值已更改为' id'属性。
现有输入:
<c03 level="subseries">
<did>
<unitid encodinganalog="isadg311" id="cnda.94.02.02">D1148/2/2</unitid>
<unittitle encodinganalog="isadg312 marc245">Bundle</unittitle>
<unitdate encodinganalog="isadg313 marc260" normal="19350701/19750108">1 Jul 1935-8 Jan 1975; n.d.</unitdate>
<physdesc encodinganalog="isadg315 marc300">
<extent>1 bundle; 11 items.</extent>
<genreform />
<physfacet />
</physdesc>
</did>
期望的结果:
<c03 level="subseries">
<did>
<unitid encodinganalog="isadg311">cnda.94.02.02</unitid>
<unittitle encodinganalog="isadg312 marc245">Bundle</unittitle>
<unitdate encodinganalog="isadg313 marc260" normal="19350701/19750108">1 Jul 1935-8 Jan 1975; n.d.</unitdate>
<physdesc encodinganalog="isadg315 marc300">
<extent>1 bundle; 11 items.</extent>
<genreform />
<physfacet />
</physdesc>
<physloc>D1148/2/2</physloc>
</did>
一些一般性问题,并非所有&#39; unitid&#39;节点有一个&#39; id&#39;属性以及这种情况下的&#39; unitid&#39;价值应该保留。此外,还有一些记录显示这个&#39; id&#39;属性在&#39;做过&#39;节点,例如
<did id="uni.07.01.06.14">
<unitid encodinganalog="isadg311">P4A/5/9</unitid>
在这种情况下,&#39; id&#39;属性来自&#39;做过&#39;节点应该成为&lt; unitid&#39;具有&#39; unitid&#39;的值被设定为&#39; physloc&#39; e.g。
<did>
<unitid encodinganalog="isadg311">uni.07.01.06.14</unitid>
<physloc>P4A/5/9</physloc>
我目前的样式表是这样的:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes"/>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<xsl:template match="did">
<xsl:param name="physid" select="unitid"/>
<xsl:param name="eadid">
<xsl:choose>
<xsl:when test="@id">
<xsl:value-of select="@id" />
</xsl:when>
<xsl:when test="unitid/@id">
<xsl:value-of select="unitid/@id"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="unitid"/>
</xsl:otherwise>
</xsl:choose>
</xsl:param>
<xsl:copy>
<xsl:copy-of select="*" />
<physloc><xsl:value-of select="$physid" /></physloc>
<unitid><xsl:value-of select="$eadid" /></unitid>
</xsl:copy>
</xsl:template>
对于没有&#39; id&#39; &lt; unitid&#39;中的属性结果是:
<did>
<repository encodinganalog="marc852">
<corpname>
University of Liverpool,
<subarea>Special Collections and Archives</subarea> </corpname>
</repository>
<unitid countrycode="GB" repositorycode="141" encodinganalog="isadg311">CNDA</unitid>
<physloc>CNDA</physloc>
<unitid>CNDA</unitid>
<physloc>CNDA</physloc>
<unitid>CNDA</unitid>
哪里有“id”&#39;在&lt; unitid&#39;:
中<did>
<unitid encodinganalog="isadg311" id="cnda.94.01.17">D1148/1/17</unitid>
<unittitle encodinganalog="isadg312 marc245">Poem</unittitle>
<unitdate encodinganalog="isadg313 marc260" normal="19000101/19591231">n.d.</unitdate>
<physdesc encodinganalog="isadg315 marc300">
<extent>1 item; 2 pieces.</extent>
<genreform/>
<physfacet/>
</physdesc>
<physloc>D1148/1/17</physloc>
<unitid>cnda.94.01.17</unitid>
<physloc>D1148/1/17</physloc>
<unitid>cnda.94.01.17</unitid>
</did>
那里有一个&#39; id&#39;在&#39;做过&#39;节点:
<did>
<unitid encodinganalog="isadg311">D1148/2/2</unitid>
<unittitle encodinganalog="isadg312 marc245">Bundle</unittitle>
<unitdate encodinganalog="isadg313 marc260" normal="19350701/19750108">1 Jul 1935-8 Jan 1975; n.d.</unitdate>
<physdesc encodinganalog="isadg315 marc300">
<extent>1 bundle; 11 items.</extent>
<genreform/>
<physfacet/>
</physdesc>
<physloc>D1148/2/2</physloc>
<unitid>cnda.94.02.02</unitid>
<physloc>D1148/2/2</physloc>
<unitid>D1148/2/2</unitid>
</did>
如何更改样式表以便我只获得一个&#39; unitid&#39;和&#39; physloc&#39;有正确的价值?我正在使用的XML文件是嵌套的,并且&#39; unitid&#39;节点可以出现在多个级别。
答案 0 :(得分:1)
再看一下我的样式表,看起来它是模板中的<xsl:copy>
语句。删除它已经成功了。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes"/>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<xsl:template match="did">
<xsl:param name="physid" select="unitid"/>
<xsl:param name="eadid">
<xsl:choose>
<xsl:when test="@id">
<xsl:value-of select="@id" />
</xsl:when>
<xsl:when test="unitid/@id">
<xsl:value-of select="unitid/@id"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="unitid"/>
</xsl:otherwise>
</xsl:choose>
</xsl:param>
<xsl:copy-of select="*" />
<physloc><xsl:value-of select="$physid" /></physloc>
<unitid><xsl:value-of select="$eadid" /></unitid>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
你的转变分解为这些基本规则:
unitid/@id
属性unitid
文字值应取自@id
属性physloc
元素,并接收旧的unitid
文字值这些规则中的每一个都可以转换为一个单独的模板来实现它。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- 1. identity template copies everything as is -->
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<!-- 2. if there is an id attribute, delete it -->
<xsl:template match="unitid/@id" />
<!-- 3. move the value of the id attribute into the element value -->
<xsl:template match="unitid[@id]/text()">
<xsl:value-of select="../@id" />
</xsl:template>
<!-- 4. create a <physloc> element inside <did> -->
<xsl:template match="did[not(physloc)]">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
<physloc><xsl:value-of select="unitid" /></physloc>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
使用此样式表,您的输入将转换为所需的输出:
<c03 level="subseries">
<did>
<unitid encodinganalog="isadg311">cnda.94.02.02</unitid>
<unittitle encodinganalog="isadg312 marc245">Bundle</unittitle>
<unitdate encodinganalog="isadg313 marc260" normal="19350701/19750108">1 Jul 1935-8 Jan 1975; n.d.</unitdate>
<physdesc encodinganalog="isadg315 marc300">
<extent>1 bundle; 11 items.</extent>
<genreform/>
<physfacet/>
</physdesc>
<physloc>D1148/2/2</physloc>
</did>
</c03>
请注意,teplates 2和3仅与具有@id
属性的特定情况相匹配。如果没有,则<unitid>
元素只是按原样复制。换句话说,如果输入已经是所需的格式,则不会发生任何事情。