Xml 恢复XSLT中的数据
我有以下XML数据:Xml 恢复XSLT中的数据,xml,xslt,xpath,Xml,Xslt,Xpath,我有以下XML数据: <root> (...) <items> <item> (...) <custom1>blabla</custom1> <custom2>blibli</custom2> <custom3>blublu</custom3> <custom4/> <custom5/
<root>
(...)
<items>
<item>
(...)
<custom1>blabla</custom1>
<custom2>blibli</custom2>
<custom3>blublu</custom3>
<custom4/>
<custom5/>
<custom6/>
<custom7/>
<custom8/>
<custom9/>
<custom10/>
(...)
</item>
<item>
(...)
<custom1/>
<custom2/>
<custom3/>
<custom4>bloblo</custom1>
<custom5>bleble</custom2>
<custom6/>
<custom7/>
<custom8/>
<custom9/>
<custom10/>
(...)
</item>
</items>
(...)
</root>
(...)
(...)
布拉布拉
blibli
布鲁
(...)
(...)
布洛
bleble
(...)
(...)
我需要(使用XSLT 1.0)将其转换为:
<root>
(...)
<items>
<item>
(...)
<refVariables>
<refVariable uuid="var1" value="blabla"/>
<refVariable uuid="var2" value="blibli"/>
<refVariable uuid="var3" value="blublu"/>
</refVariables>
(...)
</item>
<item>
(...)
<refVariables>
<refVariable uuid="var4" value="bloblo"/>
<refVariable uuid="var5" value="bleble"/>
</refVariables>
(...)
</item>
</items>
(...)
<variables>
<variable uuid="var1">
<name>var1</name>
<comment>Migrated</comment>
</variable>
<variable uuid="var2">
<name>var2</name>
<comment>Migrated</comment>
</variable>
<variable uuid="var3">
<name>var3</name>
<comment>Migrated</comment>
</variable>
<variable uuid="var4">
<name>var4</name>
<comment>Migrated</comment>
</variable>
<variable uuid="var5">
<name>var5</name>
<comment>Migrated</comment>
</variable>
</variables>
</root>
(...)
(...)
(...)
(...)
(...)
(...)
var1
迁移
var2
迁移
var3
迁移
var4
迁移
var5
迁移
要继续,我需要:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="items">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
<variables>
<xsl:for-each select="item/*[string(.)]">
<variable uuid="var{substring-after(name(), 'custom')}">
<name>
<xsl:value-of select="concat('var', substring-after(name(), 'custom'))"/>
</name>
</variable>
</xsl:for-each>
</variables>
</xsl:template>
<xsl:template match="item">
<xsl:copy>
<refVariables>
<xsl:apply-templates select="*[string(.)]"/>
</refVariables>
</xsl:copy>
</xsl:template>
<xsl:template match="*[starts-with(name(), 'custom')]">
<refVariable uuid="var{substring-after(name(), 'custom')}" value="{.}" />
</xsl:template>
</xsl:stylesheet>
多亏了Kirill Polishchuk,我从他那里借用了用于跳过空节点的
字符串(.
的“技巧”,这里是我自己的(可能是最终的)解决方案,它似乎工作得很好:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:variable name="legacy-custom-prefix" select="'custom'"/>
<!-- A helper to Generate a variable reference for N non empty same customX fields -->
<xsl:template name="variableGenerator">
<xsl:param name="nodes"/>
<xsl:for-each select="$nodes[string(.)][1]">
<variable uuid="var{substring-after(name(), $legacy-custom-prefix)}">
<name><xsl:value-of select="concat('var', substring-after(name(), $legacy-custom-prefix))"/></name>
<comment>Migrated</comment>
</variable>
</xsl:for-each>
</xsl:template>
<!-- Generate all variables declarations -->
<xsl:template match="/root">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<variables>
<xsl:call-template name="variableGenerator"><xsl:with-param name="nodes" select="//custom1"/></xsl:call-template>
<xsl:call-template name="variableGenerator"><xsl:with-param name="nodes" select="//custom2"/></xsl:call-template>
<xsl:call-template name="variableGenerator"><xsl:with-param name="nodes" select="//custom3"/></xsl:call-template>
<xsl:call-template name="variableGenerator"><xsl:with-param name="nodes" select="//custom4"/></xsl:call-template>
<xsl:call-template name="variableGenerator"><xsl:with-param name="nodes" select="//custom5"/></xsl:call-template>
<xsl:call-template name="variableGenerator"><xsl:with-param name="nodes" select="//custom6"/></xsl:call-template>
<xsl:call-template name="variableGenerator"><xsl:with-param name="nodes" select="//custom7"/></xsl:call-template>
<xsl:call-template name="variableGenerator"><xsl:with-param name="nodes" select="//custom8"/></xsl:call-template>
<xsl:call-template name="variableGenerator"><xsl:with-param name="nodes" select="//custom9"/></xsl:call-template>
<xsl:call-template name="variableGenerator"><xsl:with-param name="nodes" select="//custom10"/></xsl:call-template>
</variables>
</xsl:copy>
</xsl:template>
<!-- Substitute legacy customX fields by variable references -->
<xsl:template match="/root/items/item">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
<refVariables>
<xsl:for-each select="node()[starts-with(name(), $legacy-custom-prefix)][string(.)]">
<xsl:element name="refVariable">
<xsl:attribute name="uuid">
<xsl:value-of select="concat('var', substring-after(name(.), $legacy-custom-prefix))"/>
</xsl:attribute>
<xsl:attribute name="value">
<xsl:value-of select="node()"/>
</xsl:attribute>
</xsl:element>
</xsl:for-each>
</refVariables>
</xsl:copy>
</xsl:template>
<!-- remove all custom fields for everyone -->
<xsl:template match="/root/items/item/*[starts-with(name(), 'custom')]"/>
</xsl:stylesheet>
迁移
谢谢,我们就快到了,但仍然有重复。我刚刚纠正了我的代码示例,因为它没有我真正的word版本准确。