剧情TWIST:如何组合多个XML文件并输出多个节点?

时间:2018-08-07 21:21:25

标签: xml xslt

在这里和其他许多页面上搜索了类似问题的解决方案后,我认为这很容易。但是,我无法使它正常工作。

我有大量的XML文件,它们都使用相同的结构。某些分支可以重复。为了将它们组合到一个文档中,我创建了一个使用document函数的样式表。另外,我使用for-each在msItem的每个实例中输出节点。

但是,输出有缺陷。我没有给出每个节点的值以及相应节点的值,而是获得了所有节点的值。对于每个msItem,我都会得到完全相同的乱码行。

谁可以提供帮助?

Ms_01.xml

<?xml version="1.0" encoding="UTF-8"?>
<TEI version="5.0" xmlns="http://www.tei-c.org/ns/1.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<msDesc>
    <msIdentifier>
        <idno type="shelfmark">Ms. 01</idno>
    </msIdentifier>
    <msContents>
        <msItem>
            <locus from="1r" to="15v">1r-15v</locus>
            <author>
                <persName xml:lang="en">Aristotle</persName>
                <persName xml:lang="gr">…</persName>
            </author>
            <title xml:lang="en">On the sould</title>
            <title xml:lang="he">…</title>
        </msItem>
        <msItem>
            <locus from="16r" to="25v">16r-25v</locus>
            <author>
                <persName xml:lang="en">Aristotle</persName>
                <persName xml:lang="gr">…</persName>
            </author>
            <title xml:lang="en">On Generation and Corruption</title>
            <title xml:lang="he">…</title>
        </msItem>
        <msItem>
            <locus from="26r" to="35v">26r-35v</locus>
            <author>
                <persName xml:lang="en">Aristotle</persName>
                <persName xml:lang="gr">…</persName>
            </author>
            <title xml:lang="en">Physics</title>
            <title xml:lang="he">…</title>
        </msItem>
    </msContents>
</msDesc>
</TEI>

Ms_02.xml

<?xml version="1.0" encoding="UTF-8"?>
<TEI version="5.0" xmlns="http://www.tei-c.org/ns/1.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<msDesc>
    <msIdentifier>
        <idno type="shelfmark">Ms. 02</idno>
    </msIdentifier>
    <msContents>
        <msItem>
            <locus from="1r" to="15v">1r-15v</locus>
            <author>
                <persName xml:lang="en">Plato</persName>
                <persName xml:lang="gr">…</persName>
            </author>
            <title xml:lang="en">Ion</title>
            <title xml:lang="he">…</title>
        </msItem>
        <msItem>
            <locus from="16r" to="25v">16r-25v</locus>
            <author>
                <persName xml:lang="en">Plato</persName>
                <persName xml:lang="gr">…</persName>
            </author>
            <title xml:lang="en">Republic</title>
            <title xml:lang="he">…</title>
        </msItem>
    </msContents>
</msDesc>
</TEI>

booklist_test.xml

<?xml version="1.0"?>
<library>
    <title>Selected Manuscripts</title>
    <book filename="Ms_01.xml"/>
    <book filename="Ms_02.xml"/>
</library>

XSLT文件

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:tei="http://www.tei-c.org/ns/1.0">
  <xsl:output method="text" indent="yes"/>
  <!--<xsl:strip-space elements="*"/>-->
  <xsl:template match="/">
    <xsl:for-each select="document(/library/book/@filename)//tei:msItem">
      <xsl:sort select="//tei:persName[@xml:lang='en']"/>
      <xsl:apply-templates select="//tei:persName[@xml:lang='en']"/>
      <xsl:text>; </xsl:text>
      <xsl:apply-templates select="//tei:title[@xml:lang='en']"/>
      <xsl:text>; </xsl:text>
      <xsl:apply-templates select="//tei:idno[@type='shelfmark']"/>
      <xsl:text>; </xsl:text>
      <xsl:apply-templates select="//tei:locus"/>
      <xsl:text>
</xsl:text>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

所需的输出:

Aristotle; On the soul; Ms. 01; 1r-15v
Aristotle; On Generation and Corruption; Ms. 01; 16r-25v
Aristotle; Physics; Ms. 01; 26r-35v
Plato; Ion; Ms. 02; 1r-15v
Plato; Republic; Ms. 02; 16r-25v

我得到的输出:

AristotleAristotleAristotle; On the souldOn Generation and CorruptionPhysics; Ms. 01; 1r-15v16r-25v26r-35v
AristotleAristotleAristotle; On the souldOn Generation and CorruptionPhysics; Ms. 01; 1r-15v16r-25v26r-35v
AristotleAristotleAristotle; On the souldOn Generation and CorruptionPhysics; Ms. 01; 1r-15v16r-25v26r-35v
PlatoPlato; IonRepublic; Ms. 02; 1r-15v16r-25v
PlatoPlato; IonRepublic; Ms. 02; 1r-15v16r-25v

1 个答案:

答案 0 :(得分:0)

您的错误仅仅是因为您使用了//...之类的 global 路径,而不是下面的特定路径。通过使用像"//tei:persName[@xml:lang='en']"这样的全局XPath表达式,您确实在每次迭代中都引用了所有tei:persName。但是,通过使用下面的特定路径(如我在下面的"tei:author/tei:persName[@xml:lang='en']"中进行的操作),您只能相对于current()节点匹配此路径一次。

因此,整个模板/应充满特定的 XPath表达式,从而为您提供所需的输出:

  <xsl:template match="/">
    <xsl:for-each select="document(/library/book/@filename)/tei:TEI/tei:msDesc/tei:msContents/tei:msItem">
      <xsl:sort select="tei:author/tei:persName[@xml:lang='en']"/>
      <xsl:apply-templates select="tei:author/tei:persName[@xml:lang='en']"/>
      <xsl:text>; </xsl:text>
      <xsl:apply-templates select="tei:title[@xml:lang='en']"/>
      <xsl:text>; </xsl:text>
      <xsl:apply-templates select="../../tei:msIdentifier/tei:idno[@type='shelfmark']"/>
      <xsl:text>; </xsl:text>
      <xsl:apply-templates select="tei:locus"/>
      <xsl:text>&#xa;</xsl:text>
    </xsl:for-each>
  </xsl:template>

输出为:

Aristotle; On the sould; Ms. 01; 1r-15v
Aristotle; On Generation and Corruption; Ms. 01; 16r-25v
Aristotle; Physics; Ms. 01; 26r-35v
Plato; Ion; Ms. 02; 1r-15v
Plato; Republic; Ms. 02; 16r-25v