Xml 每个空间分隔属性值的XSL

Xml 每个空间分隔属性值的XSL,xml,xslt,xslt-2.0,tei,Xml,Xslt,Xslt 2.0,Tei,对于我的研究项目,我有这个XML/TEI文档 <TEI xmlns="http://www.tei-c.org/ns/1.0" > <body> <div> <p> <span target="#" type="passage" ana="Tag957 Tag874"> <span target="#" ana=""/>

对于我的研究项目,我有这个XML/TEI文档

<TEI xmlns="http://www.tei-c.org/ns/1.0" >
<body>
    <div>
        <p>
            <span target="#" type="passage" ana="Tag957 Tag874">
                <span target="#" ana=""/>
            </span>
            <seg><date when="1980-01-01" type="date_seg"/>blabla blabla
                 blabla blablablabla blablablabla blablablabla blablablabla bl
            </seg>
            <span target="#" type="passage" ana="Tag1657 ">
                <span target="#" ana=""/>
            </span>
            <seg><date from="1980-01-03" to="1980-01-05" type="date_seg"/>blabla
            </seg>
        </p>
    </div>
</body>
</TEI>
我试过这样做,但我不知道如何表示每次都应用于一个属性的值

<xsl:template match="tei:p">
        <xsl:for-each select="tei:span">
                <xsl:value-of select="./@ana"/>
                <xsl:text>;</xsl:text>
            <xsl:if test="following-sibling::tei:seg/tei:date/@from or following-sibling::tei:seg/tei:date/@to">
                <xsl:value-of select="following-sibling::tei:seg/tei:date/@from"/>
            </xsl:if>
            <xsl:if test="following-sibling::tei:seg/tei:date/@when">
                <xsl:value-of select="following-sibling::tei:seg/tei:date/@when"/>
            </xsl:if>
                <xsl:text>;</xsl:text>
                <xsl:value-of select="string-length(following-sibling::tei:seg)"/>
                <xsl:text>;</xsl:text>
                <xsl:value-of select="$newLine"/>
        </xsl:for-each>
</xsl:template>

;
;
;

您只为
span
元素创建了一个单循环。这还不够

实际上,对于每个这样的
span
,您必须:

  • 阅读
    ana
    属性
  • 用一个空格来实现它的智能化(如果可以的话,可以使用XSLT2.0,它有这个功能)
对于每个生成的标记(不是整个
@ana
),您必须对每个
循环执行内部

  • 仅查找以下
    seg
    同级及其子
    date
    元素的第一个
    select=“following sibling::tei:seg[1]/tei:date”
    (注意我添加了[1])
  • 检查它是否包含必需的属性(
    from
    to
    when
如果有,则:

  • 打印从当前
    ana
    属性提取的当前令牌
  • 根据您的需要打印所需的日期(从当前
    date
    元素)
  • 打印其余要打印的内容
这只是一个草图,我省略了一些细节,比如在各自的变量中保留两个循环的当前值


我希望它能帮助您获得最终结果。

您只为
span
元素创建了一个单循环。这还不够

实际上,对于每个这样的
span
,您必须:

  • 阅读
    ana
    属性
  • 用一个空格来实现它的智能化(如果可以的话,可以使用XSLT2.0,它有这个功能)
对于每个生成的标记(不是整个
@ana
),您必须对每个
循环执行内部

  • 仅查找以下
    seg
    同级及其子
    date
    元素的第一个
    select=“following sibling::tei:seg[1]/tei:date”
    (注意我添加了[1])
  • 检查它是否包含必需的属性(
    from
    to
    when
如果有,则:

  • 打印从当前
    ana
    属性提取的当前令牌
  • 根据您的需要打印所需的日期(从当前
    date
    元素)
  • 打印其余要打印的内容
这只是一个草图,我省略了一些细节,比如在各自的变量中保留两个循环的当前值


我希望它能帮助您获得最终结果。

使用XSLT2.0,您可以使用
标记化
来识别属性值中的不同值,然后您可以将代码重写为

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xpath-default-namespace="http://www.tei-c.org/ns/1.0">
    <xsl:template match="p">
        <xsl:for-each select="span">
            <xsl:variable name="span" select="."/>
            <xsl:for-each select="tokenize(@ana, '\s+')[normalize-space()]">
              <xsl:value-of select="."/>
              <xsl:text>;</xsl:text>
              <xsl:if test="$span/following-sibling::seg[1]/date/@from or $span/following-sibling::seg[1]/date/@to">
                <xsl:value-of select="$span/following-sibling::seg[1]/date/@from"/>
              </xsl:if>
              <xsl:if test="$span/following-sibling::seg/date/@when">
                <xsl:value-of select="$span/following-sibling::seg/date/@when"/>
              </xsl:if>
              <xsl:text>;</xsl:text>
              <xsl:value-of select="string-length($span/following-sibling::seg[1])"/>
              <xsl:text>;</xsl:text>
              <xsl:value-of select="'&#10;'"/>
            </xsl:for-each>    
        </xsl:for-each>
    </xsl:template>
</xsl:transform>

;
;
;

在线。

使用XSLT 2.0,您可以使用
标记化
来标识属性值中的不同值,然后您可以将代码重写为

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xpath-default-namespace="http://www.tei-c.org/ns/1.0">
    <xsl:template match="p">
        <xsl:for-each select="span">
            <xsl:variable name="span" select="."/>
            <xsl:for-each select="tokenize(@ana, '\s+')[normalize-space()]">
              <xsl:value-of select="."/>
              <xsl:text>;</xsl:text>
              <xsl:if test="$span/following-sibling::seg[1]/date/@from or $span/following-sibling::seg[1]/date/@to">
                <xsl:value-of select="$span/following-sibling::seg[1]/date/@from"/>
              </xsl:if>
              <xsl:if test="$span/following-sibling::seg/date/@when">
                <xsl:value-of select="$span/following-sibling::seg/date/@when"/>
              </xsl:if>
              <xsl:text>;</xsl:text>
              <xsl:value-of select="string-length($span/following-sibling::seg[1])"/>
              <xsl:text>;</xsl:text>
              <xsl:value-of select="'&#10;'"/>
            </xsl:for-each>    
        </xsl:for-each>
    </xsl:template>
</xsl:transform>

;
;
;

在线地址。

XSLT-1.0

我创建一个递归模板来标记
ana
属性中的值,并为每个跨度调用它。我必须在第8行添加一个空格,以便模板工作:


在线链接:XSLT-1.0

我创建一个递归模板来标记
ana
属性中的值,并为每个跨度调用它。我必须在第8行添加一个空格,以便模板工作:


在线链接:

哪个XSLT处理器您使用/可以使用哪个XSLT版本?我在Oxon软件中使用XSLT处理器,我选择的是Saxon-HE9.6.0.7哪个XSLT处理器您使用/可以使用哪个XSLT版本?我在Oxon软件中使用XSLT处理器,我选择的是Saxon-HE9.6.0.7谢谢,它在我提供的XML上运行良好。我在我的其他文件上测试了它,我不得不在第二个xsl中添加seg[1]:如果因为它正在检索所有其他同级的日期,那么它在我提供的XML上工作得很好。我在其他文件上测试了它,我不得不在第二个xsl:if-cause中添加seg[1],因为它正在检索所有其他兄弟姐妹的日期。谢谢你的建议。我在其他文件上测试了它,但它似乎只是在@ana中有多个值的进程跨度,而不是只有一个值的进程跨度。奇怪的是:-)@r。让示例XML中的第二个span在
ana
属性中有额外的空间。我利用它来标记属性值。可能其他
span
没有该附加属性,因此被忽略。谢谢您的建议。我在其他文件上测试了它,但它似乎只是在@ana中有多个值的进程跨度,而不是只有一个值的进程跨度。奇怪的是:-)@r。让示例XML中的第二个span在
ana
属性中有额外的空间。我利用它来标记属性值。可能其他
span
没有该附加属性,因此被忽略。
<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" omit-xml-declaration="yes" encoding="UTF-8"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="tei:p">
        <xsl:for-each select="tei:span">
            <xsl:call-template name="recurse_ana">
                <xsl:with-param name="ana_val" select="substring-before(./@ana,' ')"/>
                <xsl:with-param name="remaining-ana-val" select="substring-after(concat(./@ana,' '),' ')"/>
                <xsl:with-param name="seg" select="following-sibling::tei:seg[1]"/>
            </xsl:call-template>
        </xsl:for-each>
    </xsl:template>
    <xsl:template name="recurse_ana">
        <xsl:param name="ana_val"/>
        <xsl:param name="remaining-ana-val"/>
        <xsl:param name="seg"/>
        <xsl:if test="string-length($ana_val) > 0"><xsl:value-of select="$ana_val"/>
            <xsl:value-of select="';'"/>
            <xsl:value-of select="$seg/tei:date/(@when|@from)"/>
            <xsl:value-of select="';'"/>
            <xsl:value-of select="string-length($seg)"/>
            <xsl:value-of select="'&#x0D;'"/>
            <xsl:call-template name="recurse_ana">
                <xsl:with-param name="ana_val" select="substring-before($remaining-ana-val,' ')"/>
                <xsl:with-param name="remaining-ana-val" select="substring-after($remaining-ana-val,' ')"/>
                <xsl:with-param name="seg" select="$seg"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>
Tag957;1980-01-01;105 
Tag874;1980-01-01;105 
Tag1657;1980-01-03;19