【问题标题】:Create a table from a tei document xml with xslt使用 xslt 从 tei 文档 xml 创建表
【发布时间】:2013-06-03 17:30:29
【问题描述】:

我有一个这样的 XML:

<body>
      <div type="capitolo">
          <div n="7" type="pag">
            <head>Prologo</head>
            <p>
               Le tenebre stavano avanzando.
            </p>
            <p>
                <said rend="pre(«) post(»)">Meglio Rientrare.</said> <name type="gar">Gared</name> osservò i boschi attorno a 
                loro farsi più oscuri. <said rend="pre(«) post(»)">I bruti sono morti.</said>
            </p>
            <p>
               <said rend="pre(«) post(»)">Da quando hai paura dei morti?</said> C'era l'accenno di un sorriso sui lineamenti di 
                ser <name type="way">Waymar Royce</name>.
            </p>
            <p>
               <name type="gar">Gared</name> non raccolse. Era un uomo in età, oltre i cinquanta, e di e di nobili ne aveva visti andare 
                e venire molti. <said rend="pre(«) post(»)">Ciò che è morto resta morto</said>         disse <said rend="pre(«) post(»)">e noi non 
                dovremmo averci niente a che fare.</said>
            </p>
            <p>
               <said rend="pre(«) post(»)">Che prova abbiamo che sono davvero morti?</said> chiese <name type="way">Royce</name> a bassa voce.
            </p>
            <p>
               <said rend="pre(«) post(»)"><name type="will">Will</name> li ha visti. Come prova, a me basta.</said>
            </p>
            <p>
               <name type="will">Will</name> sapeva che prima o poi l'avrebbero trascinato nella discussione. Aveva sperato che accadesse dopo, 
                piuttosto che prima. <said rend="pre(«) post(»)">Mia madre diceva che i morti non parlano</said> s'intromise.
            </p>
            <p>
                <said rend="pre(«) post(»)">Davvero, <name type="will">Will</name>?</said> rispose <name type="way">Royce</name>. 
                <said rend="pre(«) post(»)">E' la stessa cosa che mi diceva la mia balia. Mai credere a quello che si sente vicino alle tette di una donna. 
                C'è sempre da imparare, perfino dai morti.</said>
            </p>
            <p>
                La foresta piena d'ombre rimandò echi della voce di ser <name type="way">Waymar</name>. Troppi echi, troppo forti e definiti.</p>
            <p>
                <said rend="pre(«) post(»)">Ci aspetta una lunga cavalcata</said> insistè <name type="gar">Gared</name> 
                <said rend="pre(«) post(»)"> Otto giorni, forse nove. E sta calando la notte.</said>
            </p></div></body>

我必须用 XSLT 创建一个 html 表,其中

第 1 列:对于我考虑不同@types 的每个“名称”标签,标签名称的值(如果类型是新的时间,请不要再写一次该名称)

第 2 列:对于在该行中选择的类型,我们可以找到该 @type 的所有 @n

你能帮帮我吗?

【问题讨论】:

  • 请向我们展示您希望收到的 XML 结果。
  • 也请您在此之前所做的工作和研究。
  • 我希望接收的输出是具有类似内容的 html 文件: 出现在页面:7-9-11
    [Name of character]

标签: xml html xslt


【解决方案1】:

欢迎来到 Stack Overflow!

一些建议。如果您显示当前正在尝试运行的代码,您通常会在 Stack Overflow 上获得更好的问题答案,但该代码无法正常运行。 (如果您没有编写任何代码,大多数 Stack Overflow 读者会假设您只是希望别人为您编写代码,他们会忽略您的问题或指责您懒惰。这意味着如果您没有代码,因为您不知道如何进行,所以您需要非常仔细地提出您的问题。)Stack Overflow FAQ on asking good quesitons 值得一读,并提供了很好的建议。 Eric Raymond 和 Rick Moen 的文章 "How to ask questions the smart way" 也很有帮助。

首先,您可能希望使用key 属性而不是type 属性来区分由name 元素命名的个人。

然后,如果您不确定如何解决您的 XSLT 问题,请尝试将其分解为更小的问题。

  • 首先尝试一个样式表,该样式表生成一个带有文本“Watch this space”的 HTML 表格。

    您的 XSLT 将在某处有一个模板,该模板发出包含一行的表格所需的 HTML 元素。

  • 然后尝试为输入中的每个name 元素创建一个包含一行的表格。 (这还不是你想要的,因为它会包含许多多次出现的名称条目,但它比“Watch this space”更接近,所以它是进步。)

    您的 XSLT 将有一个模板(可能在 body 的模板中)发出 HTML table 元素,以及一个用于name 的模板为name 的出现发出一个表格行。

  • 然后尝试想办法让每个不同的名称,或者更确切地说,每个不同的key(或type)属性在表中只出现一次。在 XSLT 2.0 中,函数distinct-values() 在这方面很有用;在 XSLT 1.0 中,通常的方法是使 name 元素仅在它是具有其键值的第一个元素时才生成表行。您可以在适当模板的match 模式或xsl:choose/xsl:when 元素的test 中使用XPath 表达式来测试给定元素是否是同类中的第一个。

    检查给定name 元素是否是第一个具有其键值的元素的幼稚方法有时会很慢。加快速度的常用方法是使用 XSLT key 函数和一种称为 Muenchian Grouping 的技术(在 Web 上搜索它;您会发现很多命中)。如果您是 XSLT 的新手,Muenchian Grouping 可能很难理解,所以我建议您不要打扰它,如果这种简单的方法对您当前的需求足够快——也就是说,如果您不花很多钱是时候希望 XSLT 运行得更快了。

    根据您的操作方式,您的样式表现在将有一个 name 模板,其中包含一个 xsl:choose,如果它是第一次出现的键,则做一件事,如果不是,则做另一件事,或者它将有一个模板用于第一次出现的情况和一个模板用于非首次出现的情况。

  • 最后,让样式表生成使用给定名称的位置的完整列表。执行此操作的简单方法是使用模板中 xsl:apply-templates 上的 select 属性来首次出现每个名称键。

如果您是 XSLT 的新手,您可能会遇到这些步骤中的任何一个问题。试试看,尽力而为,然后在 Stack Overflow 上提问,显示代码来说明你是如何尝试解决问题的。祝你好运。

【讨论】:

  • 好的,非常感谢!这真的很有用……现在我遇到了一个问题……想象一下,我有不止一次类型为“pag”的潜水,并且每个潜水都有不同的属性 n 值。我如何获得 n 的所有值,在那里我可以找到我正在查看的类型的名称?希望我能很好地解释这个问题(对不起我的英语不好!)
  • 这是答案中的最后一个项目符号。假设您有变量 $type 中的类型(在与该类型匹配的name 的第一个实例的模板内)。现在你的任务是:对于每个带有@type = $type 的名称,找到页码并将其写出来。我会调用xsl:apply-templates select="//name[@type = $type]" mode="pagenums" 并在模式pagenums 中为name 编写一个模板,该模板使用&lt;xsl:value-of select="ancestor::tei:div[@type='pag']/@n"/&gt; 写出页码。有些人会改用xsl:for-each(但我避免使用for-each:它经常让我感到困惑。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多