Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.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

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如何复制特定的XML子树_Xml_Xslt - Fatal编程技术网

使用XSLT如何复制特定的XML子树

使用XSLT如何复制特定的XML子树,xml,xslt,Xml,Xslt,我已经找到了正确使用xsl:copy(XSLT1.0)的各种答案,但它们似乎都使用了相同的,可以很好地复制整个文档。我正在努力匹配一个特定的节点,我想复制并应用模板到它的子树 例如,给定此XML文档: <MyXML> <a> <b>c</b> </a> <d> <e>f</e> </d> <g x="y"> <foo bar="

我已经找到了正确使用xsl:copy(XSLT1.0)的各种答案,但它们似乎都使用了相同的
,可以很好地复制整个文档。我正在努力匹配一个特定的节点,我想复制并应用模板到它的子树

例如,给定此XML文档:

<MyXML>
  <a>
    <b>c</b>
  </a>
  <d>
    <e>f</e>
  </d>
  <g x="y">
    <foo bar="baz">
      <item name="aname">quux</item>
      <item name="bname">xyzzy</item>
    </foo>
  </g>
</MyXML>

我想把
改成
可能很容易。我一直在猜测各种其他排列,但我无法得到我需要的结果。

如果您只想处理
foo
元素,只需添加一个与根节点匹配的模板,并将模板仅应用于所需的节点(从而删除所有其他节点):

XSLT1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="/">
    <xsl:apply-templates select="MyXML/g/foo"/>
</xsl:template>

<xsl:template match="item[@name='bname']/text()">
    <xsl:value-of select="translate(., 'y', 'Y')" />
</xsl:template>

</xsl:stylesheet>



请注意,这假设最多有一个
foo
元素,否则结果将不是格式良好的XML文档。

标识模板(带有xsl:copy的模板)不仅复制整个文档:它复制您向其抛出的任何节点。具体地说,您“抛出一个节点”的方式是通过执行xsl:apply templates选择该节点。因此,可能您所缺少的只是根模板(
match=“/”
)级别的
。我想我不明白匹配是如何工作的-所有xsl:template声明都有隐含的顺序吗?有没有办法说明这三个“扩展”是如何协同工作的?我的直觉让我认为每个声明都与上面的声明是串行工作的,这是错误的吗?我也不明白为什么在根(“/”)级别的匹配中需要额外的声明,以及为什么我不能只使用两个xsl:template声明。@Matt默认情况下,从根节点开始,然后从根节点向下推进-除非样式表介入。请记住,除非您重写它们,否则也会应用一些。在这种情况下,如果将这些元素留给它们处理,则会将
b
e
的文本节点复制到输出树中。
<foo bar="baz">
  <item name="aname">quux</item>
  <item name="bname">xYzzY</item>
</foo>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="/">
    <xsl:apply-templates select="MyXML/g/foo"/>
</xsl:template>

<xsl:template match="item[@name='bname']/text()">
    <xsl:value-of select="translate(., 'y', 'Y')" />
</xsl:template>

</xsl:stylesheet>