因此,我有一个具有以下格式的XML文件:
[...]
<level1>
<para id="1"/>
<image type="photo" artist="Joe"/>
<para id="2"/>
<para id="3"/>
<level2>
<para id="4"/>
<image type="pencil" artist="Bob"/>
<para id="5"/>
</level2>
<para id="6"/>
<image type="oil" artist="Joe"/>
</level1>
[...]
问题在于图像属性并不总是正确的,并且它们没有唯一的标识符。我有另一个具有所有正确属性的文件。我正在尝试编写一个将删除不正确属性的转换,然后从其他文件放置正确属性。
这是我到目前为止的内容:
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- ============================================================= -->
<xsl:variable name="target" select="document('correct.xml')//image"/>
<xsl:template match="image">
<xsl:variable name="vPath1">
<xsl:for-each select="ancestor-or-self::*">
<xsl:value-of select="concat('/',name())"/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="vPath2">
<xsl:for-each select="$target[ancestor-or-self::*]">
<xsl:value-of select="concat('/',name())"/>
</xsl:for-each>
</xsl:variable>
<xsl:copy>
<xsl:if test="$vPath1=$vPath2">
<xsl:copy-of select="$target/@*"/>
</xsl:if>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
这样可以成功删除我所有不正确的属性,但不会放置正确的属性。似乎我的'if'语句从未奏效,但我知道路径是相同的。我做错什么了?
我的correct.xml看起来像这样(这也是输出的样子):
[...]
<level1>
<para id="1"/>
<image type="pencil" artist="Joe"/>
<para id="2"/>
<para id="3"/>
<level2>
<para id="4"/>
<image type="photo" artist="Steve"/>
<para id="5"/>
</level2>
<para id="6"/>
<image type="oil" artist="Bob"/>
</level1>
[...]
如果两个XML文档的结构完全匹配,则可以使用位置谓词匹配路径。这将确保您正在比较唯一路径。
否则,您必须匹配ID或其他内容。如果是这种情况,请告诉我,我可以id
在生成路径时更新我的答案以使用(或其他)属性。
XML输入
<level1>
<para id="1"/>
<image type="photo" artist="Joe"/>
<para id="2"/>
<para id="3"/>
<level2>
<para id="4"/>
<image type="pencil" artist="Bob"/>
<para id="5"/>
</level2>
<para id="6"/>
<image type="oil" artist="Joe"/>
</level1>
正确的XML(我将其命名为so_good.xml。)
<level1>
<para id="1"/>
<image type="pencil" artist="Joe"/>
<para id="2"/>
<para id="3"/>
<level2>
<para id="4"/>
<image type="photo" artist="Steve"/>
<para id="5"/>
</level2>
<para id="6"/>
<image type="oil" artist="Bob"/>
</level1>
XSLT 2.0(也可用作1.0)
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="good" select="document('so_good.xml')"/>
<xsl:template name="getPath">
<xsl:for-each select="ancestor-or-self::*">
<xsl:value-of select="concat('/',local-name())"/>
<!--Predicate is only output when needed.-->
<xsl:if test="(preceding-sibling::*|following-sibling::*)[local-name()=local-name(current())]">
<xsl:value-of select="concat('[',count(preceding-sibling::*[local-name()=local-name(current())])+1,']')"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="image">
<xsl:variable name="currPath">
<xsl:call-template name="getPath"/>
</xsl:variable>
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="$good//image" mode="new-attrs">
<xsl:with-param name="currPath" select="$currPath"/>
</xsl:apply-templates>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="image" mode="new-attrs">
<xsl:param name="currPath"/>
<xsl:variable name="goodPath">
<xsl:call-template name="getPath"/>
</xsl:variable>
<xsl:if test="$currPath=$goodPath">
<xsl:copy-of select="@*"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
XML输出
<level1>
<para id="1"/>
<image type="pencil" artist="Joe"/>
<para id="2"/>
<para id="3"/>
<level2>
<para id="4"/>
<image type="photo" artist="Steve"/>
<para id="5"/>
</level2>
<para id="6"/>
<image type="oil" artist="Bob"/>
</level1>
为了帮助显示正在比较的内容,可以将其添加xsl:message
到“ new-attrs”模式的“ image”模板中:
<xsl:message>Comparing "<xsl:value-of select="$currPath"/>" (currPath) to "<xsl:value-of select="$goodPath"/>" (goodPath). Do they match? <xsl:value-of select="boolean($currPath=$goodPath)"/></xsl:message>
您应该看到类似以下的消息:(对不起,该图片)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句