【问题标题】:Removing Attributes from XSLT and working with result set从 XSLT 中删除属性并使用结果集
【发布时间】:2011-09-25 14:33:21
【问题描述】:

是否可以从 XSLT 中删除 xml 属性并使用生成的转换?

换句话说,我有以下 XML:

<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet type="text/xsl" href="XML_TEST.xslt"?>
<report xmlns="abc123">
<book>
<page id="22">

</page>
<page id="23">

</page>
</book>
</report>

我知道我可以使用以下 XSLT 来剥离属性:

 <xsl:template match ="@*" >
            <xsl:attribute name ="{local-name()}" >
                <xsl:value-of select ="." />
            </xsl:attribute>
            <xsl:apply-templates/>
        </xsl:template>
        <xsl:template match ="*" >
            <xsl:element name ="{local-name()}" >
                <xsl:apply-templates select ="@* | node()" />
            </xsl:element>
  </xsl:template>

但如果我想读取值,请使用以下模板

<xsl:template match="report">
    <xsl:for-each select="book/page">
        <xsl:value-of select="@id"/>
    </xsl:for-each>
</xsl:template>

我可以将该模板链接到前两个的输出吗?

提前致谢,

-R.

【问题讨论】:

  • 你需要两个输出吗?如果不是这样,从单个 xslt 中获得所需的内容可能会更容易。你能添加你想要得到的输出吗?
  • 好问题,+1。请参阅我的答案以获得两个完整、简短、简单且容易的解决方案。 :)
  • +1 表示好问题 TITLE
  • @cordsen:我要获取的值是 id,因此最终输出应该只是呈现简单的内容,例如:2223。

标签: xml xslt transform chaining


【解决方案1】:

许多转换最好分成一个管道,其中管道的每个阶段执行一个简单的任务。

您可以在单个样式表中进行多阶段转换(通过将结果保存在变量中,尤其是使用 XSLT 2.0),或者您可以使用多个样式表来进行。您可以使用多种技术(XProc、Cocoon、Orbeon、Ant、xmlsh)或从您自己的 Java/C# 代码控制涉及多个样式表的管道。使用多个样式表的优点是管道的组件具有高度可重用性。

【讨论】:

    【解决方案2】:

    这个问题有些奇怪:我看不出你的问题的标题与内容有何匹配

    在标题中,您要求进行 两遍 转换,其中第一遍必须删除属性,第二遍必须对其进行处理。

    在内容中,您显示了两个模板,它们输出节点和属性的本地名称,然后,您在另一个模板中显示您希望使用属性获取它们的值。 .. :)

    根据@Dimitre 对您问题的内容的回答(我认为这并没有解决真正的问题)我会尝试回答您问题的标题 ,这似乎更有趣(并且可以回答)。


    从 XSLT 中删除属性 ...

    要删除属性(并获得没有命名空间的转换),您可以使用Identity Transformation。因为您想要多遍,所以您必须在第一遍中将转换的内容复制到一个变量上。

    您可以使用modes 将进程寻址到第一遍中的元素。

    ...并使用结果集

    要使用结果集(正式称为result tree fragment),您需要使用对第一遍中定义的变量的引用来应用模板。欢迎!这是第二遍 :)

    在 XSLT 2.0 中比在 XSLT 1.0 中更容易访问两次转换,因为 XSLT 2.0 能够将模板应用于 RTF。在 XSLT 1.0 中,您将需要一个名为 node-set() 的特定扩展函数。


    XSLT 2.0 将如下所示(纯示例):

    <xsl:stylesheet   
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"   
        xmlns:x="abc123"   
        version="2.0">
    
        <xsl:output indent="yes" omit-xml-declaration="yes"/>   
        <xsl:strip-space elements="*"/> 
    
        <xsl:template match="/">
            <xsl:variable name="FirstPass">
                <xsl:copy>
                    <xsl:apply-templates select="/" mode="FirstPass"/>
                </xsl:copy>
            </xsl:variable>
    
            <xsl:apply-templates select="$FirstPass/report/book/page"/>
        </xsl:template>
    
        <xsl:template match="node()" mode="FirstPass">
            <xsl:element name="{local-name()}">
                <xsl:apply-templates select ="node()" mode="FirstPass"/>
            </xsl:element>
        </xsl:template>
    
        <xsl:template match="page">
            <xsl:value-of select="count(@*)"/>
        </xsl:template>
    
    </xsl:stylesheet> 
    

    带有结果(应用于您的输入示例)

    00
    

    XSLT 1.0 看起来非常相似,但变换根元素:

    <xsl:stylesheet   
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"   
    xmlns:x="abc123"
    xmlns:exslt="http://exslt.org/common"
    version="2.0">
    

    第二关

     <xsl:apply-templates select="exslt:node-set($FirstPass)/report/book/page"/>
    

    【讨论】:

    • 通过“属性”,OP实际上意味着删除默认命名空间。
    【解决方案3】:

    是否可以删除xml 来自 XSLT 的属性并使用 结果转换?

    是的,只要搜索“multi-pass transformation”,你会发现很多答案都有很好的代码示例。

    但是,对于您要执行的操作,这种转换链接过于复杂且完全没有必要

    只需使用:

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:x="abc123" >
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
    
     <xsl:template match="x:page">
      <xsl:value-of select="@id"/>
     </xsl:template>
    </xsl:stylesheet>
    

    如果事先不知道 XML 文档的默认命名空间,您仍然可以一次生成所需的结果

    <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="*[name()='page']">
      <xsl:value-of select="@id"/>
     </xsl:template>
    </xsl:stylesheet>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-26
      • 1970-01-01
      相关资源
      最近更新 更多