xsl 通配符匹配以排除自身
xsl wildcard match to exclude itself
如果 Child
s 在 Identifier
元素中有重复值,我想创建新元素 create_duplicate
,但我不想匹配当前节点本身。当前 //Identifier/text()
也匹配自身。有没有办法排除它,只匹配所有其他 Child/Identifier
s?
XML:
<Document>
<List>
<Child>
<Identifier>19961202</Identifier>
</Child>
<Child>
<Identifier>19961203</Identifier>
</Child>
</List>
<WebResponse>
<Product>
<WebIdentifier>19961202</WebIdentifier>
</Product>
<Product>
<WebIdentifier>19961203</WebIdentifier>
</Product>
</WebResponse>
</Document>
XSLT:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"></xsl:output>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Child">
<xsl:copy>
<xsl:apply-templates select="@* | node()"></xsl:apply-templates>
<operation>
<xsl:choose>
<xsl:when test="Identifier/text() = //Identifier/text()">
<xsl:value-of select="'create_duplicate'"/>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="Identifier/text() = //WebIdentifier/text()">
<xsl:value-of select="'update'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'create'"/>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</operation>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
结果:
<Document>
<List>
<Child>
<Identifier>19961202</Identifier>
<!-- I would expect 'update' here as it should skip itself-->
<operation>create_duplicate</operation>
</Child>
<Child>
<Identifier>19961203</Identifier>
<!-- I would expect 'update' here as it should skip itself-->
<operation>create_duplicate</operation>
</Child>
</List>
<WebResponse>
<Product>
<WebIdentifier>19961202</WebIdentifier>
</Product>
<Product>
<WebIdentifier>19961203</WebIdentifier>
</Product>
</WebResponse>
</Document>
我猜你可以分组,然后用一个键检查是否有交叉引用:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:template match="Document/List">
<xsl:copy>
<xsl:for-each-group select="Child" group-by="Identifier">
<xsl:apply-templates select="current-group()"/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="Child[key('webid', Identifier)]">
<xsl:copy>
<operation>{if (position() eq 1) then 'update' else 'duplicate'}</operation>
</xsl:copy>
</xsl:template>
<xsl:template match="Child[not(key('webid', Identifier))]">
<xsl:copy>
<operation>{if (position() eq 1) then 'create' else 'duplicate'}</operation>
</xsl:copy>
</xsl:template>
<xsl:output method="xml" indent="yes"/>
<xsl:key name="webid" match="Product" use="WebIdentifier"/>
<xsl:mode on-no-match="shallow-copy"/>
</xsl:stylesheet>
或者使用两个键,一个用于“分组”,第二个用于交叉引用检查:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:key name="id" match="Child" use="Identifier"/>
<xsl:template match="Child[. is key('id', Identifier)[1]][key('webid', Identifier)]">
<xsl:copy>
<operation>update</operation>
</xsl:copy>
</xsl:template>
<xsl:template match="Child[not(. is key('id', Identifier)[1])][key('webid', Identifier)]">
<xsl:copy>
<operation>duplicate</operation>
</xsl:copy>
</xsl:template>
<xsl:template match="Child[. is key('id', Identifier)[1]][not(key('webid', Identifier))]">
<xsl:copy>
<operation>create</operation>
</xsl:copy>
</xsl:template>
<xsl:template match="Child[not(. is key('id', Identifier)[1])][not(key('webid', Identifier))]">
<xsl:copy>
<operation>duplicate</operation>
</xsl:copy>
</xsl:template>
<xsl:output method="xml" indent="yes"/>
<xsl:key name="webid" match="Product" use="WebIdentifier"/>
<xsl:mode on-no-match="shallow-copy"/>
如果 Child
s 在 Identifier
元素中有重复值,我想创建新元素 create_duplicate
,但我不想匹配当前节点本身。当前 //Identifier/text()
也匹配自身。有没有办法排除它,只匹配所有其他 Child/Identifier
s?
XML:
<Document>
<List>
<Child>
<Identifier>19961202</Identifier>
</Child>
<Child>
<Identifier>19961203</Identifier>
</Child>
</List>
<WebResponse>
<Product>
<WebIdentifier>19961202</WebIdentifier>
</Product>
<Product>
<WebIdentifier>19961203</WebIdentifier>
</Product>
</WebResponse>
</Document>
XSLT:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"></xsl:output>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Child">
<xsl:copy>
<xsl:apply-templates select="@* | node()"></xsl:apply-templates>
<operation>
<xsl:choose>
<xsl:when test="Identifier/text() = //Identifier/text()">
<xsl:value-of select="'create_duplicate'"/>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="Identifier/text() = //WebIdentifier/text()">
<xsl:value-of select="'update'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'create'"/>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</operation>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
结果:
<Document>
<List>
<Child>
<Identifier>19961202</Identifier>
<!-- I would expect 'update' here as it should skip itself-->
<operation>create_duplicate</operation>
</Child>
<Child>
<Identifier>19961203</Identifier>
<!-- I would expect 'update' here as it should skip itself-->
<operation>create_duplicate</operation>
</Child>
</List>
<WebResponse>
<Product>
<WebIdentifier>19961202</WebIdentifier>
</Product>
<Product>
<WebIdentifier>19961203</WebIdentifier>
</Product>
</WebResponse>
</Document>
我猜你可以分组,然后用一个键检查是否有交叉引用:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:template match="Document/List">
<xsl:copy>
<xsl:for-each-group select="Child" group-by="Identifier">
<xsl:apply-templates select="current-group()"/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="Child[key('webid', Identifier)]">
<xsl:copy>
<operation>{if (position() eq 1) then 'update' else 'duplicate'}</operation>
</xsl:copy>
</xsl:template>
<xsl:template match="Child[not(key('webid', Identifier))]">
<xsl:copy>
<operation>{if (position() eq 1) then 'create' else 'duplicate'}</operation>
</xsl:copy>
</xsl:template>
<xsl:output method="xml" indent="yes"/>
<xsl:key name="webid" match="Product" use="WebIdentifier"/>
<xsl:mode on-no-match="shallow-copy"/>
</xsl:stylesheet>
或者使用两个键,一个用于“分组”,第二个用于交叉引用检查:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:key name="id" match="Child" use="Identifier"/>
<xsl:template match="Child[. is key('id', Identifier)[1]][key('webid', Identifier)]">
<xsl:copy>
<operation>update</operation>
</xsl:copy>
</xsl:template>
<xsl:template match="Child[not(. is key('id', Identifier)[1])][key('webid', Identifier)]">
<xsl:copy>
<operation>duplicate</operation>
</xsl:copy>
</xsl:template>
<xsl:template match="Child[. is key('id', Identifier)[1]][not(key('webid', Identifier))]">
<xsl:copy>
<operation>create</operation>
</xsl:copy>
</xsl:template>
<xsl:template match="Child[not(. is key('id', Identifier)[1])][not(key('webid', Identifier))]">
<xsl:copy>
<operation>duplicate</operation>
</xsl:copy>
</xsl:template>
<xsl:output method="xml" indent="yes"/>
<xsl:key name="webid" match="Product" use="WebIdentifier"/>
<xsl:mode on-no-match="shallow-copy"/>