通过xslt将属性从一个xml文件移动到另一个

Beeblebrox42

因此,我有一个具有以下格式的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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

将元素从一个xml文件移动到另一个xml文件

来自分类Dev

将某些字符从一个文件移动到另一个文件

来自分类Dev

将特定属性从一个对象移动到另一个对象

来自分类Dev

PHPStorm将文件从一个拆分移动到另一个

来自分类Dev

将大文件从一个 Google 帐户移动到另一个?

来自分类Dev

在XSLT-2.0中将空格分隔的令牌从一个属性移动到另一个属性的最佳方法是什么?

来自分类Dev

使用XSLT 2将元素从一个位置移动到另一个位置

来自分类Dev

将文件从一个文件夹移动到另一个C#

来自分类Dev

如何将 N 行从一个文件移动到另一个文件

来自分类Dev

为什么Python docx或lxml将属性从一个节点移动到另一个节点?

来自分类Dev

将属性从一个对象移动到Javascript中的另一个对象

来自分类Dev

使用 xslt-3 将元素从 xml 文件移动到另一个 xml 元素

来自分类Dev

将数据从一个MySQL表移动到另一个

来自分类Dev

运动将精灵从一个点移动到另一个点

来自分类Dev

将屏幕从一个虚拟桌面移动到另一个

来自分类Dev

将数据从一个mysql表移动到另一个

来自分类Dev

将数据从一个MySQL表移动到另一个

来自分类Dev

将元素从一个地方移动到另一个地方

来自分类Dev

将元素从一个包移动到另一个包

来自分类Dev

将记录从一个集合移动到另一个 PyMongo

来自分类Dev

将 CTabItem 从一个 CTabFolder 移动到另一个 CTabFolder

来自分类Dev

C:将元素从一个列表移动到另一个列表

来自分类Dev

将图像从一个地方移动到另一个地方

来自分类Dev

将 html 元素从一个节点移动到另一个节点

来自分类Dev

使用Paramiko将文件从一个目录移动到另一个目录

来自分类Dev

将Spotfire页面(或“仪表盘”)从一个Spotfire文件移动到另一个

来自分类Dev

使用Java NIO将文件从一个目录移动到另一个目录

来自分类Dev

如何将文件从一个目录移动到另一个目录?

来自分类Dev

将最新文件从一个目录移动到另一个目录

Related 相关文章

  1. 1

    将元素从一个xml文件移动到另一个xml文件

  2. 2

    将某些字符从一个文件移动到另一个文件

  3. 3

    将特定属性从一个对象移动到另一个对象

  4. 4

    PHPStorm将文件从一个拆分移动到另一个

  5. 5

    将大文件从一个 Google 帐户移动到另一个?

  6. 6

    在XSLT-2.0中将空格分隔的令牌从一个属性移动到另一个属性的最佳方法是什么?

  7. 7

    使用XSLT 2将元素从一个位置移动到另一个位置

  8. 8

    将文件从一个文件夹移动到另一个C#

  9. 9

    如何将 N 行从一个文件移动到另一个文件

  10. 10

    为什么Python docx或lxml将属性从一个节点移动到另一个节点?

  11. 11

    将属性从一个对象移动到Javascript中的另一个对象

  12. 12

    使用 xslt-3 将元素从 xml 文件移动到另一个 xml 元素

  13. 13

    将数据从一个MySQL表移动到另一个

  14. 14

    运动将精灵从一个点移动到另一个点

  15. 15

    将屏幕从一个虚拟桌面移动到另一个

  16. 16

    将数据从一个mysql表移动到另一个

  17. 17

    将数据从一个MySQL表移动到另一个

  18. 18

    将元素从一个地方移动到另一个地方

  19. 19

    将元素从一个包移动到另一个包

  20. 20

    将记录从一个集合移动到另一个 PyMongo

  21. 21

    将 CTabItem 从一个 CTabFolder 移动到另一个 CTabFolder

  22. 22

    C:将元素从一个列表移动到另一个列表

  23. 23

    将图像从一个地方移动到另一个地方

  24. 24

    将 html 元素从一个节点移动到另一个节点

  25. 25

    使用Paramiko将文件从一个目录移动到另一个目录

  26. 26

    将Spotfire页面(或“仪表盘”)从一个Spotfire文件移动到另一个

  27. 27

    使用Java NIO将文件从一个目录移动到另一个目录

  28. 28

    如何将文件从一个目录移动到另一个目录?

  29. 29

    将最新文件从一个目录移动到另一个目录

热门标签

归档