2010-08-08 49 views
2

我被困在试图在这些限制内工作,我正在使用XSLT 1.0 {under .net}。 我希望能够做到以下几点: 我是的xsl:for-each'ing通过一组类型的节点的带有修改的XSLT副本

<node> 
    <data> unknown unstructured xml </data> 
    <owner></owner> 
    </node> 

我想能够输出

<node> 
    <data> unknown unstructured xml </data> 
    <!--RESULT of calling an XSL template with certain parameters --> 
    </node> 

从我的搜索到目前为止,我想我可以做这样的事情在here

<xsl:copy> 
     <xsl:apply-template name="findownerdetails"> 
      <xsl:with-param name="data" select="something" /> 
     </xsl:apply-template> 
    </xsl:copy> 

但这显然是无效的。任何建议如何得到这个工作或实现类似的目标?恐怕我不能直接调用apply-templates作为我想要的模板,这取决于我为每个节点元素创建的数据。

任何意见理解

+0

好问题(+1)。请参阅我的答案,以获得完全符合XSLT精神的最简单解决方案,利用最基本的XSLT设计模式 - 使用和重写身份规则。 – 2010-08-08 23:21:48

回答

1
<xsl:template match="node"> 
    <node> 
    <xsl:copy-of select="data"/> 
    <!-- assuming this next bit in your question example 
    is something you are happy with --> 
    <xsl:call-template name="findownerdetails"> 
     <xsl:with-param name="data" select="something" /> 
    </xsl:call-template> 
    </node> 
</xsl:template> 
+0

谢谢,我希望我能想到一段时间后会这样做。 供参考: 如果节点元素有一些我需要复制的未知属性会发生什么? 也有可能做一个 GreyCloud 2010-08-08 23:00:51

+1

你可以做它回答你的问题。在更复杂的情况下,或者来自不同命名空间的“所有者”元素的可能性,与重写身份(如Dimitre的答案中)变得更加优雅(我们可以通过Dimitre的扩展和我处理更复杂案例的答案;我的在一定的复杂度下更加简洁,Dimitre在它之上,这也是Dimitre更通用,每个XSLT编码人员都应该知道的原因)。 (p.s.,如果以上帮助,接受答案将是很好的)。 – 2010-08-08 23:27:24

+0

感谢额外的信息乔恩,看起来像它会做的伎俩。由于Dimitre的答案不处理传递参数,你的答案,我会接受你的答案 - 谢谢:) – GreyCloud 2010-08-09 10:12:24

5

这是最好的使用并覆盖解决的问题的一个典型的例子的identity rule

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

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

<xsl:template match="owner"> 
    <owner-details> 
     <xsl:value-of select="."/> 
    </owner-details> 
</xsl:template> 
</xsl:stylesheet> 

当这种转化是在这个XML施加文档(基于所提供的具有附加属性和所有者详细信息的XML文档):

<node attr1="x" attr2="y"> 
    <data> unknown unstructured xml </data> 
    <owner> 
     <details> 
      <name>John Smith </name> 
      <profession>XSLT programmer</profession> 
     </details> 
    </owner> 
</node> 

的通缉的结果产生

<node attr1="x" attr2="y"> 
    <data> unknown unstructured xml </data> 
    <owner-details>John Smith XSLT programmer</owner-details> 
</node> 

请注意

  1. 身份模板拷贝文档中的每个节点 “原样” 的递归的时尚。

  2. 我们只覆盖我们想要以另一种方式处理的元素的标识模板。任何模板(其匹配模式比标识模板的匹配模式更具体)都会覆盖它--XSLT处理器将始终为节点选择最具体的匹配模板。

  3. 使用并重写身份规则是最根本的,功能最强大,最普遍和最优雅的XSLT设计模式。它几乎在所有XSLT转换中都使用:用于删除/重命名/修改/添加特定节点并保持所有其他节点不变。

  4. OP在评论中建议此解决方案不允许传递参数。这不是真的。任何模板(包括身份规则)都可以写入参数 - 当需要时。在这种特殊情况下,它是而不是需要通过模板传递参数。

  5. 匹配owner模板不需要调用另一个模板 - 所有的老板 - 具体的处理都可以在这里完成。

+0

嗨Dimitre,感谢您的解决方案,我看到了类似的答案在另一个线程中,但恐怕它不起作用,因为我无法通过调用传递任何参数。 – GreyCloud 2010-08-09 10:11:10

+0

@GreyCloud:你不明白:1.你可以通过任何模板传递参数。对于您的问题中的问题,这是不需要的。修改问题,以便它需要传递参数,我会告诉你如何。 2.在匹配'owner'的模板中,您不需要调用另一个模板并将paramrter(s)传递给它 - 您可以在该模板中处理'owner'元素(及其子树) - 并且是我的答案所暗示的。 – 2010-08-09 11:32:25

+0

如何通过“”传递参数? – GreyCloud 2010-08-09 12:23:33