我有一个非结构化的Adlib XML文件,其中包含以下格式的数据:
<record>
...
<dimension.type>height</dimension.type>
<dimension.type>width</dimension.type>
<dimension.type>height</dimension.type>
<dimension.type>width</dimension.type>
<dimension.type>depth</dimension.type>
<dimension.notes>without frame</dimension.notes>
<dimension.notes>without frame</dimension.notes>
<dimension.notes>with frame</dimension.notes>
<dimension.notes>with frame</dimension.notes>
<dimension.notes>with frame</dimension.notes>
<dimension.value>28.0</dimension.value>
<dimension.value>47.9</dimension.value>
<dimension.value>41.4</dimension.value>
<dimension.value>62.9</dimension.value>
<dimension.value>8.0</dimension.value>
...
</record>我想要做的是将其转换为以下格式:
<record>
...
<dimension>
<notes>without frame</notes>
<height>28.0</height>
<width>47.9</width>
</dimension>
<dimension>
<notes>with frame</notes>
<height>41.4</height>
<width>62.9</width>
<depth>8.0</depth>
</dimension>
...
</record>然而,我有点卡住了,因为这些节点引用相同位置的其他节点中的信息。我确实想出了以下XSLT:
<xsl:template match="dimension.value">
<xsl:variable name="pos" select="position()"/>
<dimension>
<xsl:choose>
<xsl:when test="../dimension.type[$pos] = 'height'">
<height><xsl:value-of select="."/></height>
</xsl:when>
<xsl:when test="../dimension.type[$pos] = 'width'">
<width><xsl:value-of select="."/></width>
</xsl:when>
<xsl:when test="../dimension.type[$pos] = 'depth'">
<depth><xsl:value-of select="."/></depth>
</xsl:when>
</xsl:choose>
<notes>
<xsl:value-of select="../dimension.notes[$pos]"/>
</notes>
</dimension>
</xsl:template>它会生成以下格式的数据:
<dimension>
<height>28.0</height>
<notes>without frame</notes>
</dimension>
<dimension>
<width>47.9</width>
<notes>without frame</notes>
</dimension>
<dimension>
<height>41.4</height>
<notes>with frame</notes>
</dimension>
<dimension>
<width>62.9</width>
<notes>with frame</notes>
</dimension>
<dimension>
<depth>8.0</depth>
<notes>with frame</notes>
</dimension>但是这不会对note部分进行分组,这会使处理结果变得更容易(现在我用代码来解决这个问题,但是XSLT必须有一种方法来解决这个问题,对吧?)任何帮助(指向相关信息或相关XSLT片段的指针)都将非常感谢……
顺便说一句,我翻译了XML/XSLT的一部分以使其更容易理解,when:test实际上检查荷兰语描述,并将它们转换为等效的英语标记……
发布于 2011-08-30 20:42:17
下面是一个XSLT 1.0解决方案:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="record">
<xsl:copy>
<xsl:apply-templates select="dimension.notes[1]" mode="group"/>
</xsl:copy>
</xsl:template>
<xsl:template match="dimension.notes" mode="group">
<dimension>
<notes>
<xsl:value-of select="."/>
</notes>
<xsl:apply-templates select="."/>
</dimension>
<xsl:apply-templates select="following-sibling::dimension.notes[not(. = current())][1]" mode="group"/>
</xsl:template>
<xsl:template match="dimension.notes">
<xsl:variable name="pos">
<xsl:number/>
</xsl:variable>
<xsl:apply-templates select="../dimension.type[position() = $pos]">
<xsl:with-param name="pos" select="$pos"/>
</xsl:apply-templates>
<xsl:apply-templates select="following-sibling::dimension.notes[1][. = current()]"/>
</xsl:template>
<xsl:template match="dimension.type">
<xsl:param name="pos"/>
<xsl:element name="{.}">
<xsl:value-of select="../dimension.value[position() = $pos]"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>发布于 2011-08-30 19:36:22
下面是一些使用XSLT 2.0的示例:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="record">
<xsl:copy>
<xsl:for-each-group select="dimension.notes" group-adjacent=".">
<dimension>
<notes>
<xsl:value-of select="current-grouping-key()"/>
</notes>
<xsl:apply-templates select="current-group()"/>
</dimension>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="dimension.notes">
<xsl:variable name="pos" as="xs:integer">
<xsl:number/>
</xsl:variable>
<xsl:apply-templates select="../dimension.type[position() eq $pos]">
<xsl:with-param name="pos" select="$pos"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="dimension.type">
<xsl:param name="pos"/>
<xsl:element name="{.}">
<xsl:value-of select="../dimension.value[position() eq $pos]"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>我不确定它能不能解决你的问题,因为"...“您的示例中的元素可能需要更复杂的编码,这取决于那里到底可以出现什么类型的元素以及您想要对它们做什么。
https://stackoverflow.com/questions/7241961
复制相似问题