【问题标题】:How can I extract xml data to create customized html tables如何提取 xml 数据以创建自定义的 html 表
【发布时间】:2016-12-01 07:24:30
【问题描述】:

希望我能用通俗易懂的方式描述问题:

我有一个包含 1000 多个条目的大型 XML 文件,这些条目必须显示在 HTML 文件中。条目(比如说员工姓名)被分组在不同的部分(部门)中。在 HTML 文件中,我必须为每个部门创建一个表格并列出所有具有某些属性的员工。

XML结构是这样的:

<section name="department_A">
  <entry name="john doe" gender="m" age="20"></entry>
  <entry name="luke smith" gender="m" age="34"></entry>
</section>
<section name="department_B">
  <entry name="jane doe" gender="f" age="25"></entry>
  <entry name="ben b" gender="m" age="43"></entry>
</section>
<section name="department_A and department_B">
  <entry name="john doe" gender="m" age="20"></entry>
  <entry name="nick fury" gender="m" age="53"></entry>
</section>
<section name="different departments">
  <entry name="ben b" gender="m" age="27">
     <desciption>Belongs to dep_B and dep_C</description>
  </entry>
  <entry name="chris h" gender="m" age="33">
     <description>Belongs to dep_C and dep_F</description>
  </entry>
</section>

在 HTML 文件中,每个部分名称显示为一个标题,每个条目是一个表格行,每个属性是一个表格列。以下 xls 文件用于此目的:

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

  <h1><a name="{@name}"> [<xsl:value-of select="@name"/>] </a></h1>

  <table>
  <tr>
    <th>Name</th>
    <th>Gender</th>
    <th>Age</th>
  </tr>

  <xsl:for-each select="entry">
  <tr>
    <td><xsl:value-of select="@name"/></td>
    <td><xsl:value-of select="@gender"/></td>
    <td><xsl:value-of select="@age"/></td>
  </tr>
  </xsl:for-each>  

到目前为止,XML 和 XSL 文件运行良好。但是,问题是我必须创建与 XML 结构更“独立”的 html 表,因为某些条目必须列在多个表中。

例如,员工“john doe”只出现在section="department_A"中,但必须在department_A、department_B和department_C的表中显示。有没有办法在不将每个条目复制到所有相关部分的情况下做到这一点?

我的方法是向相关条目添加另一个属性(例如条目名称="john doe" 性别="m" age="20" dep="department_B,department_C")。是否可以为一个部分创建表,填写该部分的所有条目(例如,department_B),然后浏览整个文档中的所有条目,检查是否有属性为“dep”的条目,其中包含的名称等于部分名称并将此条目附加到表中?

或者有没有其他方法可以做到这一点(没有 xls)?我希望描述是足够的。感谢您的帮助!

【问题讨论】:

  • 什么决定了员工应该出现在哪些(附加)部门?您说话的方式就像控制输入 XML 格式的人一样。如果你这样做了,那么我建议你使用多个 department elements,而不是使用多个子字符串标记的单个 attribute..
  • 已经有不同的部门元素了。有人添加了“dep_A & dep_B”、“dep_A & dep_C”等部分。但是,这不是一个全面的视图,因为有 30 多个部分加上“组合部分”。 .. 您查看 dep_A 的所有员工,但您不会知道这是否真的是所有名称,除非您也查看所有其他表。此外,如果您必须更改某些内容,则必须为每个实例执行此操作(因为具有所有属性的名称出现多次)。因此,我想删除这些副本,并且只为每个员工保留一个条目。
  • 好吧,是否您可以控制输入的 XML 格式?理想情况下,部门将与员工分开列出,并且每个员工对于他/她所属的每个部门都有一个department 元素(与关系数据库中的相同)。如果您无法更改格式,请编辑您的问题并显示您必须使用的格式示例。 ——附言“dep_A & dep_B”不是不同的部门元素
  • 是的,我可以控制输入 XML。但是,就像我之前提到的那样,如果我不必更改整个 XML,那么我希望有这么多条目。我的问题中有一个格式示例 - 只是包含很多条目的部分。
  • "如果我不必更改整个 XML,我希望有这么多条目" 您如何更改 XML?希望不是手动?我认为这是来自数据库或类似的输出。如果不是,那么我最初的问题仍然存在:是什么决定了员工应该出现在哪些(附加)部门?我没有在您的 XML 中看到它,那么附加信息来自哪里? -- "我的问题中有一个格式示例" 不,没有。没有一个员工拥有多个部门。

标签: html xml xslt


【解决方案1】:

我建议你试试这个作为你的起点:

XSLT 1.0 (+ EXSLT)

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
xmlns:set="http://exslt.org/sets"
xmlns:str="http://exslt.org/strings"
extension-element-prefixes="exsl set str">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="emp" match="person" use="all-attributes" />

<xsl:template match="/root">
    <xsl:variable name="people-rtf">
        <xsl:for-each select="section/entry">
            <person>
                <xsl:copy-of select="@*"/>
                <all-attributes>
                    <xsl:for-each select="@*">
                        <xsl:value-of select="."/>
                        <xsl:text>|</xsl:text>
                    </xsl:for-each>
                </all-attributes>
                <xsl:choose>
                    <xsl:when test="../@name='different departments'">
                        <xsl:for-each select="str:split(substring-after(description, 'Belongs to '), ' and ')">
                            <section>
                                <xsl:value-of select="."/>
                            </section>
                        </xsl:for-each>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:for-each select="str:split(../@name, ' and ')">
                            <section>
                                <xsl:value-of select="."/>
                            </section>
                        </xsl:for-each>
                    </xsl:otherwise>
                </xsl:choose>
            </person>
        </xsl:for-each>
    </xsl:variable>
    <xsl:variable name="people" select="exsl:node-set($people-rtf)/person" />
    <xsl:copy>
        <sections>
            <xsl:copy-of select="set:distinct($people/section)"/>
        </sections>
        <employees>
            <xsl:for-each select="set:distinct($people/all-attributes)">
                <employee>
                    <xsl:copy-of select="../@*"/>
                    <xsl:copy-of select="set:distinct(key('emp', .)/section)"/>
                </employee>
            </xsl:for-each>
        </employees>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

应用于以下输入:

XML

<root>
    <section name="department_A">
      <entry name="john doe" gender="m" age="20"></entry>
      <entry name="luke smith" gender="m" age="34"></entry>
    </section>
    <section name="department_B">
      <entry name="jane doe" gender="f" age="25"></entry>
      <entry name="ben b" gender="m" age="43"></entry>
    </section>
    <section name="department_A and department_B">
      <entry name="john doe" gender="m" age="20"></entry>
      <entry name="nick fury" gender="m" age="53"></entry>
    </section>
    <section name="different departments">
      <entry name="ben b" gender="m" age="43">
         <description>Belongs to dep_B and dep_C</description>
      </entry>
      <entry name="chris h" gender="m" age="33">
         <description>Belongs to dep_C and dep_F</description>
      </entry>
    </section>
</root>

结果将是:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <sections>
    <section>department_A</section>
    <section>department_B</section>
    <section>dep_B</section>
    <section>dep_C</section>
    <section>dep_F</section>
  </sections>
  <employees>
    <employee name="john doe" gender="m" age="20">
      <section>department_A</section>
      <section>department_B</section>
    </employee>
    <employee name="luke smith" gender="m" age="34">
      <section>department_A</section>
    </employee>
    <employee name="jane doe" gender="f" age="25">
      <section>department_B</section>
    </employee>
    <employee name="ben b" gender="m" age="43">
      <section>department_B</section>
      <section>dep_B</section>
      <section>dep_C</section>
    </employee>
    <employee name="nick fury" gender="m" age="53">
      <section>department_A</section>
      <section>department_B</section>
    </employee>
    <employee name="chris h" gender="m" age="33">
      <section>dep_C</section>
      <section>dep_F</section>
    </employee>
  </employees>
</root>

【讨论】:

    猜你喜欢
    • 2017-08-23
    • 1970-01-01
    • 2021-01-23
    • 2017-11-03
    • 2021-08-29
    • 1970-01-01
    • 1970-01-01
    • 2011-12-15
    • 1970-01-01
    相关资源
    最近更新 更多