Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
XSLT:如何修改内容以替换某些元素的副本?_Xslt - Fatal编程技术网

XSLT:如何修改内容以替换某些元素的副本?

XSLT:如何修改内容以替换某些元素的副本?,xslt,Xslt,我有一个类似以下内容的输入XML文档: <text> <p> Download the software from <link id="blah"> </p> </text> <links> <link id="blah"> <url>http://blah</url> </link> </links>

我有一个类似以下内容的输入XML文档:

<text>
    <p>
    Download the software from <link id="blah">
    </p>
</text>
    <links>
    <link id="blah">
    <url>http://blah</url>
    </link>
    </links>
<xsl:variable name="frag">
<xsl:copy-of select="text"/>
</xsl:variable>
<xsl:value-of select="$frag">


从下载软件

http://blah
我希望我的输出文档是:

<text>
    <p>
    Download the software from <a href="http://blah"> http://blah </a>
    </p>
</text>


从下载软件

也就是说:我希望按原样复制现有的输入文档节点,但也要使用扩展版本替换某些节点(例如
):基于输入文档中包含的其他信息

我尝试使用
在片段中进行第一次复制,如下所示:

<text>
    <p>
    Download the software from <link id="blah">
    </p>
</text>
    <links>
    <link id="blah">
    <url>http://blah</url>
    </link>
    </links>
<xsl:variable name="frag">
<xsl:copy-of select="text"/>
</xsl:variable>
<xsl:value-of select="$frag">

但当我输出变量时,如下所示:

<text>
    <p>
    Download the software from <link id="blah">
    </p>
</text>
    <links>
    <link id="blah">
    <url>http://blah</url>
    </link>
    </links>
<xsl:variable name="frag">
<xsl:copy-of select="text"/>
</xsl:variable>
<xsl:value-of select="$frag">

输出似乎没有保留段落标记?所以我不确定xsl副本是否复制了节点,或者只是复制了文本

如果我只放入以下内容(去掉
'wrapper'),它会在输出文档中保留标记吗

<xsl:copy-of select="text"/>

但当然,我需要首先将“link”标记重新映射到锚标记

我甚至还没有开始研究如何用链接信息替换变量的内容(当然是在一个新变量中)…

试试以下方法:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:output indent="yes"/>
    <xsl:template match="links"/>
    <xsl:template match="*|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="link">
        <xsl:variable name="link" select="normalize-space(//links/link[@id = current()/@id]/url)"/>
        <a href="{$link}">
            <xsl:value-of select="$link"/>
        </a>
    </xsl:template>
</xsl:stylesheet>

通过以下输入:

<?xml version="1.0" encoding="UTF-8"?>
    <texts>
        <text>
            <p>
                Download the software from <link id="blah"/>
            </p>
        </text>
        <links>
            <link id="blah">
                <url>http://blah</url>
            </link>
        </links>
    </texts>


从下载软件

http://blah
你会得到:

<?xml version="1.0" encoding="UTF-8"?>
<texts>
    <text>
        <p>
            Download the software from <a href="http://blah">http://blah</a>
        </p>
    </text>
</texts>


从下载软件


的xsl:copy-of
不会执行您想要的操作,因为它会创建一个精确的副本。所以不要使用它

xsl:value of
不能满足您的要求,因为它接受字符串值并忽略所有标记。所以不要使用它


您需要使用“修改的副本”设计模式,如Vincent的回答所示。这使用两个[或更多,如果需要]模板规则,一个默认规则适用于要复制而不更改的节点,另一个特定规则适用于需要修改的节点。

您应该在$frag上使用xsl:copy或xsl:apply templates,而不是xsl:value.;-)的xsl:value实际上采用了$frag的字符串值,这或多或少类似于在$frag中捕获的所有文本节点的串联。很好,但是为什么不必要地使用任何XSLT指令的长格式,例如:
。这不仅是不必要的,而且会导致代码更长,更难观察、理解和维护。请在以后的回答中尽量使用简短的形式,例如:
@DimitreNovatchev:我编辑我的帖子是为了考虑你的评论。@_VincentBiragnet:好。你用的是什么IDE?OxygenXML,我从来没有真正尝试过更改默认设置。@_VincentBiragnet:我也有氧气,有时会使用。是的,它会生成一个结束标记,但当您在开始标记的
之前输入
时,oXygen会自动删除结束标记。试试看。:)