如何使用XSLT匹配元素和输出HTML

How to match elements and output HTML using XSLT?

本文关键字:输出 HTML 元素 何使用 XSLT      更新时间:2023-09-26

http://s6.postimg.org/5zzsratqp/output.jpg <——预期输出-->

下面是一个XML文件,我已经给出了,因此我需要使用HTML, CSS, Javascript的形式显示数据&;XSLT。然而,查找标签是一项挑战,并且使用我创建的样式表,什么也没有出现。任何建议吗?由于

XML数据
<?xml-stylesheet type="text/xsl" href="stylesheet.xsl"?>
<data>
    <object instance="197784" dataInstance="41" name="Give As You Earn Flex" itemNumber="1" pageNumber="1" pagesAvailable="1">
        <property id="{00fd4f20-8e9c-414f-b34f-2abd4a4dc3fe}" name="Effective Date">
            <format id="{332f8155-7253-4dc9-896c-61a3a3d19816}" answer="30/05/2014 13:39:55" />
        </property>
        <property id="{ea61f121-1c2b-47df-91af-3806eba65c4b}" name="Benefit Type ID">
            <format id="{05b7ea73-a86f-4119-b330-0a0f5a4e0143}" answer="GAYE" />
        </property>
        <object instance="197785" dataInstance="41" name="Default (GAYE)" itemNumber="1" pageNumber="1" pagesAvailable="1">
            <property id="{7f428c44-7800-4972-ad37-a005824c251f}" name="Flex Default Amount">
                <format id="{4cf95889-2249-4270-9ce0-9e2da5fedbb7}" answer="0" />
            </property>
            <property id="{cc70d36d-5700-41bf-9370-2ec34c6c7010}" name="Flex Default Cost">
                <format id="{c7cf6728-47b3-4851-9633-f689b5391e88}" answer="0.0000" indicator="GBP" />
            </property>
        </object>
        <object instance="197786" dataInstance="41" name="Model (GAYE)" itemNumber="1" pageNumber="1" pagesAvailable="1">
            <property id="{ea123f721-1c2b-47df-91af-3806eba65c4b}" name="Chosen Charity">
                <format id="{05b7ea73-a86f-4119-b330-0a0f5a4e0143}" answer="" />
            </property>
            <property id="{bf500440-3f1a-46ea-8937-1d8c4dfea274}" name="Flex Model Amount">
                <format id="{4cf95889-2249-4270-9ce0-9e2da5fedbb7}" answer="0" />
            </property>
            <property id="{bf9af022-ba8b-46ed-b043-573c01ba2e1d}" name="Flex Model Cost">
                <format id="{c7cf6728-47b3-4851-9633-f689b5391e88}" answer="0.0000" indicator="GBP" />
            </property>
            <property id="{2d94fe41-8492-4c5d-945a-a23bb5dfcf93}" name="Amount Liable for Tax">
                <format id="{c7cf6728-47b3-4851-9633-f689b5391e88}" answer="0.0000" indicator="GBP" />
            </property>
            <property id="{8555974b-b80e-4704-9241-867cbb435523}" name="Amount Liable for NI">
                <format id="{c7cf6728-47b3-4851-9633-f689b5391e88}" answer="0.0000" indicator="GBP" />
            </property>
        </object>
        <object instance="197787" dataInstance="41" name="Requested (GAYE)" itemNumber="1" pageNumber="1" pagesAvailable="1">
            <property id="{0a113492-faed-4c6e-be73-d6c14210f0b3}" name="Flex Requested Amount">
                <format id="{4cf95889-2249-4270-9ce0-9e2da5fedbb7}" answer="0" />
            </property>
            <property id="{28db97f2-9346-498d-b0b7-724535af30c4}" name="Flex Requested Cost">
                <format id="{c7cf6728-47b3-4851-9633-f689b5391e88}" answer="0.0000" indicator="GBP" />
            </property>
        </object>
        <object instance="197788" dataInstance="41" name="Current (GAYE)" itemNumber="1" pageNumber="1" pagesAvailable="1">
            <property id="{b0424854-bbf4-4299-080e-2480e6c09172}" name="Flex Current Amount">
                <format id="{4cf95889-2249-4270-9ce0-9e2da5fedbb7}" answer="0" />
            </property>
            <property id="{2cb5ac07-a5c7-4bfd-9b15-925a6dd5ba6c}" name="Flex Current Discount Amount">
                <format id="{c7cf6728-47b3-4851-9633-f689b5391e88}" answer="0.0000" indicator="GBP" />
            </property>
            <property id="{b8a7f2fe-9590-44ca-bc3d-027c76ff3dff}" name="Flex Current Value">
                <format id="{05b7ea73-a86f-4119-b330-0a0f5a4e0143}" answer="0" />
            </property>
            <property id="{e133d446-443a-419e-812f-f6506f0101db}" name="Flex Current VAT Amount">
                <format id="{c7cf6728-47b3-4851-9633-f689b5391e88}" answer="0.0000" indicator="GBP" />
            </property>
            <property id="{16d1795a-ad48-401e-9dc4-68f76310e238}" name="Flex Current Cost">
                <format id="{c7cf6728-47b3-4851-9633-f689b5391e88}" answer="0.0000" indicator="GBP" />
            </property>
        </object>
        <Object_ID ObjectName="Give As You Earn Flex" ParentDataInstance="47" ParentObjectInstance="197759" EmployeeObjectInstance="197993" EmployeeDataInstance="47" />
        <ChildObject_ID ChildObjectName="Default (GAYE)" ChildObjectInstance="197785" />
        <ChildObject_ID ChildObjectName="Model (GAYE)" ChildObjectInstance="197786" />
        <ChildObject_ID ChildObjectName="Requested (GAYE)" ChildObjectInstance="197787" />
        <ChildObject_ID ChildObjectName="Current (GAYE)" ChildObjectInstance="197788" />
    </object>
    <variables>
        <variable type="request.querystring" name="DP" value="47:197738/47:197759/41:197784" />
        <variable type="request.querystring" name="select" value="true" />
        <variable type="ID" name="UserRole" value="Employee" />
        <variable type="date" fulldate="14/08/2014 10:17:13" ukdate="14 August 2014" shortdate="14/08/2014" year="2014" month="8" monthname="August" day="14" timeGMT="14/08/2014 09:17:13" time="14/08/2014 10:17:13" />
    </variables>
    <options mode="Any Value" type="CoverLevel" inputName="Flex Model Amount|197786|41" modelValue="0" modelAdditionalValue="" currentValue="0" currentAdditionalValue="" formatting="Currency" suffix="Donation" minimum="1" maximum="11666.67" increment="0.01" charityName="">
        <selectionText>Please select the amount that you would like to donate per pay period:</selectionText>
        <additionalSelectionText />
        <onChange>
            validateDependants('',this.value,'No');toggleDeclarationBox(this.value)
        </onChange>
        <option value="0" location="0" cost="00" alias="No Donation" validation="No Cover" />
    </options>
</data>
XSLT样式表

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
  <body>
  <h2>testing</h2>
     <xsl:for-each select="data">
      <xsl:value-of select="name"/>
        <xsl:value-of select="property"/>
        <xsl:value-of select="format"/>
      </xsl:for-each>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

注释

但是尝试使用php的XML解析器。它比XSLT麻烦得多,因为您需要开始考虑模板驱动语言而不是过程驱动语言。它可以是一个相当大的跳跃

你在评论中收到了这个建议,但我不同意。是的,XSLT可能需要范式转换,如果您不能掌握声明性本质和函数范式,这可能很难,但是一旦您掌握了它的要点,它将为您节省大量时间(例如,下面的样式表花了我大约10分钟,而在命令式c#或PHP中,它很容易花费几个小时)。通常,仅仅因为需要学习某种工具或语言就放弃使用这种工具或语言并不是一个好主意,除非替代方法非常简单,以至于会造成过度杀伤。

考虑到您的输入XML,我怀疑您的需求是微不足道的,使用XSLT可能是一件好事。是的,你需要掌握它,但同样地,你已经掌握了其他编程语言,在你能有效地使用它们之前,所有这些语言都需要一定的时间权衡。

使用实用主义程序员的建议:每年学习一门新语言,一旦你接近了。掌握XSLT需要一到两周的时间,您已经完成了今年的目标;)。

一些好的教程:

  • 部分免费的Pluralsight XSLT 1.0和2.0培训,Dimitre Novatchev,优秀的入门材料,它会让你在任何时间运行。
  • XSLT 1.0介绍
  • 更多的XSLT教程和链接在这个问题的答案。

在你的代码

<xsl:for-each select="data">

您只有一个data元素(XSLT不考虑标签,而是考虑元素,这是从开始标签到结束标签以及它包含的所有内容的整体),在其上使用for-each没有多大意义,您可以简单地删除这一行或将其替换为xsl:apply-templates

<xsl:value-of select="name"/>

由于这一行是在for-each中,焦点是在data元素上,而name在这里意味着"取一个名为name的元素,它是当前元素的子元素,即data的子元素"。在您的输入中不存在这样的子节点。事实上,根本没有名称为name的元素,只有属性,可以在XPath (XSLT用来选择节点的语言)中写成@name

<xsl:value-of select="property"/>
<xsl:value-of select="format"/>

虽然这些元素确实存在,但它们不在data的正下方,参见前面的注释。

此外,如果您有正确的焦点,它们仍然不会做任何事情,因为xsl:value-of接受节点的值,在元素的情况下(如果您愿意,在开始和结束标记之间)是该元素内的自由文本,其深度是任意的。它是而不是属性、注释或其他任何东西。在您的示例中,这些元素中没有自由文本,因此您将选择空(或空白)。

作为继续

的起点的解决方案

您给出的样式表示例代码表明您正在尝试这种技术,并且您正在努力解决焦点,上下文节点,结构,模板等概念。为了让您有一个良好的开端,我使用了您的输入XML,并制作了一个简单的XSLT样式表,在每一步上都添加了注释。

样式表适用于XSLT 1.0及以上版本,并可在浏览器内外(脱机处理器)使用。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <!-- from SO: https://stackoverflow.com/questions/32418785/displaying-xml-data -->
    <xsl:output method="html" indent="yes" />
    <!-- the root node, our starting point -->
    <xsl:template match="/">
        <html>
            <head>
                <title>Hello world!</title>
            </head>
            <body>
                <!-- instruct XSLT processor to process the children and place them under <body> -->
                <xsl:apply-templates />
            </body>
        </html>
    </xsl:template>
    <!-- what to do with elements: process their children -->
    <xsl:template match="node()">
        <xsl:apply-templates />
    </xsl:template>
    <!-- what to do if you encounter a "main" object, right under <data> -->
    <xsl:template match="data/object">
        <h1><xsl:value-of select="@name" /></h1>
        <h3>Properties:</h3>
        <xsl:apply-templates />
    </xsl:template>
    <!-- what to do with <property> elements -->
    <xsl:template match="property">
        <div style="margin:0">
            <span style="font-weight:bold"><xsl:value-of select="@name" />: </span>
            <span>
                <xsl:value-of select="format/@indicator" />
                <xsl:text> </xsl:text>
                <xsl:value-of select="format/@answer"/>
            </span>
        </div>
    </xsl:template>
    <!-- what to do with objects-under-main-object -->
    <xsl:template match="object/object">
        <h2><xsl:value-of select="@name" /></h2>
        <!-- this will apply the property elements under <object> -->
        <h3>Properties:</h3>
        <xsl:apply-templates />
    </xsl:template>
    <!-- what to do with text nodes we are not interested in (default is they get output): ignore -->
    <xsl:template match="text()" />
</xsl:stylesheet>

脱机运行这个样式表时的输出(在线时您永远不会看到输出,因此在浏览器内进行测试是一件非常痛苦的事情,您应该避免!),在我使用oXygen的情况下,但是任何支持xslt的环境(如Visual Studio、Eclipse或Stylus Studio)都可以:

<html>
  <head>
    <META http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Hello world!</title>
  </head>
  <body>
    <h1>Give As You Earn Flex</h1>
    <h3>Properties:</h3>
    <div style="margin:0"><span style="font-weight:bold">Effective Date: </span><span> 30/05/2014 13:39:55</span></div>
    <div style="margin:0"><span style="font-weight:bold">Benefit Type ID: </span><span> GAYE</span></div>
    <h2>Default (GAYE)</h2>
    <h3>Properties:</h3>
    <div style="margin:0"><span style="font-weight:bold">Flex Default Amount: </span><span> 0</span></div>
    <div style="margin:0"><span style="font-weight:bold">Flex Default Cost: </span><span>GBP 0.0000</span></div>
    <h2>Model (GAYE)</h2>
    <h3>Properties:</h3>
    <div style="margin:0"><span style="font-weight:bold">Chosen Charity: </span><span> </span></div>
    <div style="margin:0"><span style="font-weight:bold">Flex Model Amount: </span><span> 0</span></div>
    <div style="margin:0"><span style="font-weight:bold">Flex Model Cost: </span><span>GBP 0.0000</span></div>
    <div style="margin:0"><span style="font-weight:bold">Amount Liable for Tax: </span><span>GBP 0.0000</span></div>
    <div style="margin:0"><span style="font-weight:bold">Amount Liable for NI: </span><span>GBP 0.0000</span></div>
    <h2>Requested (GAYE)</h2>
    <h3>Properties:</h3>
    <div style="margin:0"><span style="font-weight:bold">Flex Requested Amount: </span><span> 0</span></div>
    <div style="margin:0"><span style="font-weight:bold">Flex Requested Cost: </span><span>GBP 0.0000</span></div>
    <h2>Current (GAYE)</h2>
    <h3>Properties:</h3>
    <div style="margin:0"><span style="font-weight:bold">Flex Current Amount: </span><span> 0</span></div>
    <div style="margin:0"><span style="font-weight:bold">Flex Current Discount Amount: </span><span>GBP 0.0000</span></div>
    <div style="margin:0"><span style="font-weight:bold">Flex Current Value: </span><span> 0</span></div>
    <div style="margin:0"><span style="font-weight:bold">Flex Current VAT Amount: </span><span>GBP 0.0000</span></div>
    <div style="margin:0"><span style="font-weight:bold">Flex Current Cost: </span><span>GBP 0.0000</span></div>
  </body>
</html>