首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >创建什么?函数、模板或?

创建什么?函数、模板或?
EN

Stack Overflow用户
提问于 2013-03-02 23:20:40
回答 2查看 163关注 0票数 2

我有以下问题,请看代码示例:

代码语言:javascript
复制
<xsl:if test="/Document/test/id">
  <TEST1>
     <xsl:value-of select="/Document/test/id"/>
   </TEST1>
</xsl:if>

我有一个巨大的xslt脚本,其中包含许多相同的代码。我想创建一个函数,但是我得到了所有的时间错误。我在问自己,这是否是解决这个问题的正确解决方案。

为了使代码具有更好的可维护性,我想使用如下代码。这不是xslt语法,因为我不知道如何使用它,而是让您知道我想要什么。

代码语言:javascript
复制
...
<xsl:something "TEST1", "/Document/test/id1" />
<xsl:something "TEST2", "/Document/test/id2" />
...

代码的可读性和可维护性会更好,尽管我不知道如何解决这个问题:-(欢迎任何建议...

致敬德克

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-03-03 00:25:07

此转换

代码语言:javascript
复制
<xsl:stylesheet version="2.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:my="my:my" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:variable name="vDoc" select="/"/>

 <xsl:template match="/">
     <xsl:sequence select="my:test(xs:QName('Test1'), /*/test/id1/string())"/>
     <xsl:sequence select="my:test(xs:QName('Test2'), /*/test/id2/string())"/>
     <xsl:sequence select="my:test(xs:QName('Test3'), /*/test/id3/string())"/>
     <xsl:sequence select="my:test(xs:QName('Test4'), /*/test/id4/string())"/>
 </xsl:template>

 <xsl:function name="my:test">
   <xsl:param name="pName" as="xs:QName"/>
   <xsl:param name="pToPresent" as="item()?"/>

   <xsl:if test="$pToPresent">
     <xsl:element name="{$pName}">
             <xsl:sequence select="$pToPresent"/>
     </xsl:element>
   </xsl:if>
 </xsl:function>
</xsl:stylesheet>

在以下XML文档上应用时为

代码语言:javascript
复制
<Document>
 <test>
  <id1>Some Id1</id1>
 </test>
 <test>
  <id2>Some Id2</id2>
 </test>
 <test>
  <id4>Some Id4</id4>
 </test>
</Document>

生成所需的正确结果:

代码语言:javascript
复制
<Test1>Some Id1</Test1>
<Test2>Some Id2</Test2>
<Test4>Some Id4</Test4>

注意到

  1. my:test()的第一个参数被声明为xs:QName类型,这保证了xsl:element指令的name属性的值始终是有效名称。
  2. my:test()的第二个参数被非常松散地声明为item()?类型,这使我们可以自由地提供任何类型的项(字符串、节点或元素,或者...)所提供的内容将“按原样”重现。
票数 2
EN

Stack Overflow用户

发布于 2013-03-03 01:27:09

我认为这是最接近你想要的:

代码语言:javascript
复制
<xsl:stylesheet version="2.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:f="custom-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <xsl:template match="/">
    <CONTENT>
      <xsl:sequence select="f:rename('TEST1', /Document/test/id1)"/>
      <xsl:sequence select="f:rename('TEST2', /Document/test/id2)"/>
    </CONTENT>
  </xsl:template>

  <xsl:function name="f:rename">
    <xsl:param name="name" as="xs:string"/>
    <xsl:param name="toWrap" />

    <xsl:if test="$toWrap">
      <xsl:element name="{$name}">
        <xsl:value-of select="$toWrap"/>
      </xsl:element>
    </xsl:if>
  </xsl:function>
</xsl:stylesheet>

在以下输入上运行此命令时:

代码语言:javascript
复制
<Document>
  <test>
    <id1>Hello!</id1>
    <id2>Hello again!</id2>
  </test>
</Document>

产生的输出为:

代码语言:javascript
复制
<CONTENT>
   <TEST1>Hello!</TEST1>
   <TEST2>Hello again!</TEST2>
</CONTENT>

您也可以尝试这样做,虽然有点冗长,但与XSLT 1.0兼容:

代码语言:javascript
复制
<xsl:stylesheet version="1.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <xsl:template match="/">
    <CONTENT>
      <xsl:apply-templates select="/Document/test/id1" mode="rename">
        <xsl:with-param name="name" select="'TEST1'" />
      </xsl:apply-templates>
      <xsl:apply-templates select="/Document/test/id2" mode="rename">
        <xsl:with-param name="name" select="'TEST2'" />
      </xsl:apply-templates>
    </CONTENT>
  </xsl:template>

  <xsl:template match="@* | node()" mode="rename">
    <xsl:param name="name" />
    <xsl:element name="{$name}">
      <xsl:value-of select="." />
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

当在上面的示例XML上运行时,同样会产生相同的输出。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15176059

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档