Xml 使用xslt解析并格式化名称

Xml 使用xslt解析并格式化名称,xml,substring,xslt-1.0,Xml,Substring,Xslt 1.0,我正试图编写一个XSLT样式表来处理作者的姓名并创建引用的APA版本。关于作者姓名的APA引文格式:如果引文的第一个要素是姓名,则列出姓名的姓氏,然后是首字母缩写。在最后一位作者之前用逗号和符号(&)分隔名称。我在这篇文章中遵循了Dimitre Novatchev的解决方案:但我没有得到我想要的结果 输入: 刘波,吉尔达D。 Primavera,Jurgene H。 库文·阿拉尔,马萨诸塞州。卢尔德A。 克鲁兹,急诊室。 卡塔库坦,M.R。 阿格巴亚尼,R.F。 期望的输出是:Lio Po

我正试图编写一个XSLT样式表来处理作者的姓名并创建引用的APA版本。关于作者姓名的APA引文格式:如果引文的第一个要素是姓名,则列出姓名的姓氏,然后是首字母缩写。在最后一位作者之前用逗号和符号(&)分隔名称。我在这篇文章中遵循了Dimitre Novatchev的解决方案:但我没有得到我想要的结果

输入:


刘波,吉尔达D。
Primavera,Jurgene H。
库文·阿拉尔,马萨诸塞州。卢尔德A。
克鲁兹,急诊室。
卡塔库坦,M.R。
阿格巴亚尼,R.F。
期望的输出是:Lio Po,G.D.,Primavera,J.H.,Cuvin Aralar,M.L.A.,Cruz,E.R.,Catacutan,M.R.,和Agbayani,R.F.

对于只有两位作者的记录:


刘波,吉尔达D。
Primavera,Jurgene H。
期望的输出是:Lio Po,G.D.,和Primavera,J.H

提前谢谢。下面是我的代码,其中一些代码取自Dimitre

<xsl:strip-space elements="*"/>

<xsl:template match="/">
    <xsl:for-each select="/names/author">
        <xsl:choose>
            <xsl:when test="count(following-sibling::text()) = 1">
                <xsl:text>&amp; </xsl:text>
                <xsl:apply-templates/>
            </xsl:when>
            <xsl:when test="count(following-sibling::text()) != 0">
                <xsl:apply-templates/>
                <xsl:text>, </xsl:text>
            </xsl:when>
        </xsl:choose>
    </xsl:for-each>
</xsl:template>

<xsl:template match="text()">
    <xsl:value-of select="substring-before(., ',')"/>

    <xsl:call-template name="replaceTokenDelims">
        <xsl:with-param name="pStr" select="concat(normalize-space(substring-after(., ',')), ' ')"/>
        <xsl:with-param name="pToken" select="' '"/>
        <xsl:with-param name="pReplacement" select="', '"/>
    </xsl:call-template>
</xsl:template>

<xsl:template name="replaceTokenDelims">
    <xsl:param name="pStr"/>
    <xsl:param name="pToken"/>
    <xsl:param name="pReplacement"/>

    <xsl:if test="$pStr">
        <xsl:value-of select="$pReplacement"/>
        <xsl:value-of select="substring(substring-before($pStr, $pToken),1,1)"/>

        <xsl:call-template name="replaceTokenDelims">
            <xsl:with-param name="pStr" select="substring-after($pStr, $pToken)"/>
            <xsl:with-param name="pToken" select="$pToken"/>
            <xsl:with-param name="pReplacement" select="$pReplacement"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

&;
, 

运行上面的代码可以得到输出:Lio Po、G、D、Primavera、J、H、Cuvin Aralar、M、L、A、Cruz、E、Catacutan、M和Agbayani、R

更新

这一个有效,我甚至亲自测试过:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:str="http://exslt.org/strings">
<xsl:output  method="text" />
<xsl:template match="/">
    <xsl:for-each select="/names/author">
    <xsl:if test="position() = last()">
        <xsl:text>&amp; </xsl:text>
    </xsl:if>
    <xsl:for-each select="str:tokenize(.,' ')">
        <xsl:choose>
          <xsl:when test="position() = 1">
            <xsl:value-of select="."></xsl:value-of>
          </xsl:when>
          <xsl:when test="substring(.,2,1) = '.'">
            <xsl:for-each select="str:tokenize(.,'.')">           
                <xsl:value-of select="concat(.,'.')"></xsl:value-of>
                <xsl:if test="position() != last()">
                    <xsl:text> </xsl:text>
                </xsl:if>
            </xsl:for-each>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="concat(substring(.,1,1),'.')"></xsl:value-of>
          </xsl:otherwise>
        </xsl:choose>       
        <xsl:choose>
          <xsl:when test="position() = last()">
            <xsl:text>, </xsl:text>
          </xsl:when>
          <xsl:otherwise>
            <xsl:text> </xsl:text>
          </xsl:otherwise>
        </xsl:choose>       

    </xsl:for-each>

    </xsl:for-each>
</xsl:template>
如果你能接受最后一个逗号;)

追加: 这是我测试过的完整java代码,看起来还行

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;

import javax.xml.transform.TransformerException;

public class XLSTTester {

    public static void main(String[] params){
        try {
            transform("d:\\workspace1\\test.xml","d:\\workspace1\\test.xsl");
        } catch (TransformerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private static void transform(String xmlFileFullPath, String xsltFileFullPath) throws TransformerException, IOException{
        File xmlFile = new File(xmlFileFullPath);
        File xsltFile = new File(xsltFileFullPath);
        StringWriter sw = new StringWriter();
        javax.xml.transform.Source xmlSource = new javax.xml.transform.stream.StreamSource(xmlFile);
        javax.xml.transform.Source xsltSource = new javax.xml.transform.stream.StreamSource(xsltFile); 
        javax.xml.transform.Result transResult = new javax.xml.transform.stream.StreamResult(sw);  

//          create an instance of TransformerFactory
        javax.xml.transform.TransformerFactory transFact = javax.xml.transform.TransformerFactory.newInstance(  );

        javax.xml.transform.Transformer trans = transFact.newTransformer(xsltSource);
        trans.transform(xmlSource, transResult);
    }

}
我想我明白了


如果我可以问一下,我们可以看看你的代码吗tried@Satya,我现在用我尝试过的代码更新了我的帖子。您的代码中似乎缺少一些内容;您有两个模板,每个模板后面都有一个作为兄弟。euler,我认为您的需求没有以清晰明确的方式描述--这是您仍然没有所需解决方案的主要原因--也许您仍然没有(定义良好的)问题@C.M.Sperberg-McQueen,对不起,我是stackoverflow的新手,因为这是我的第一篇文章,所以我很难放置代码。我现在已经编辑了代码,这两个模板实际上都在for之后。我在尝试您的代码时收到java.lang.ClassNotFoundException:http:…exslt.org.strings。我附加了完整的java代码,请尝试并给我反馈。因为我已经成功地运行了它。Mostafa,非常感谢您的努力,但我很抱歉地告诉您,我只是xsl的新手,对java不太熟悉,我不想告诉您,但老实说,我不知道如何处理您附带的java代码。关于我想要的输出,我想用一个空格分隔首字母(例如Cruz,E.R.到Cruz,E.R.):)欢迎您,没问题的朋友。告诉我什么是xslt处理器?它不是一个java内置处理器吗?通过将多余的逗号放入变量中,成功地删除了它
因为我注意到您的输出在末尾包含两个额外的字符,一个逗号和一个空格。非常感谢mostafa.s.mirzaee的代码,我使用了其中的一些部分来实现所需的输出。干杯
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:str="http://exslt.org/strings">
<xsl:output  method="text" />
<xsl:template match="/">
    <xsl:for-each select="/names/author">
    <xsl:if test="position() = last()">
        <xsl:text>&amp; </xsl:text>
    </xsl:if>
    <xsl:for-each select="str:tokenize(.,' ')">
        <xsl:choose>
          <xsl:when test="position() = 1">
            <xsl:value-of select="."></xsl:value-of>
          </xsl:when>
          <xsl:when test="substring(.,2,1) = '.'">
            <xsl:for-each select="str:tokenize(.,'.')">           
                <xsl:value-of select="concat(.,'.')"></xsl:value-of>
                <xsl:if test="position() != last()">
                    <xsl:text> </xsl:text>
                </xsl:if>
            </xsl:for-each>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="concat(substring(.,1,1),'.')"></xsl:value-of>
          </xsl:otherwise>
        </xsl:choose>       
        <xsl:choose>
          <xsl:when test="position() = last()">
            <xsl:text>, </xsl:text>
          </xsl:when>
          <xsl:otherwise>
            <xsl:text> </xsl:text>
          </xsl:otherwise>
        </xsl:choose>       

    </xsl:for-each>

    </xsl:for-each>
</xsl:template>
Lio-Po, G. D., Primavera, J. H., Cuvin-Aralar, M. L. A., Cruz, E. R., Catacutan, M. R., & Agbayani, R. F.,     
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;

import javax.xml.transform.TransformerException;

public class XLSTTester {

    public static void main(String[] params){
        try {
            transform("d:\\workspace1\\test.xml","d:\\workspace1\\test.xsl");
        } catch (TransformerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private static void transform(String xmlFileFullPath, String xsltFileFullPath) throws TransformerException, IOException{
        File xmlFile = new File(xmlFileFullPath);
        File xsltFile = new File(xsltFileFullPath);
        StringWriter sw = new StringWriter();
        javax.xml.transform.Source xmlSource = new javax.xml.transform.stream.StreamSource(xmlFile);
        javax.xml.transform.Source xsltSource = new javax.xml.transform.stream.StreamSource(xsltFile); 
        javax.xml.transform.Result transResult = new javax.xml.transform.stream.StreamResult(sw);  

//          create an instance of TransformerFactory
        javax.xml.transform.TransformerFactory transFact = javax.xml.transform.TransformerFactory.newInstance(  );

        javax.xml.transform.Transformer trans = transFact.newTransformer(xsltSource);
        trans.transform(xmlSource, transResult);
    }

}
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:str="http://exslt.org/strings">
<xsl:output method="text"/>
<xsl:template match="/">
    <xsl:for-each select="/names/author">
        <xsl:variable name="firstname">
            <xsl:value-of select="substring-after(., ', ')"/>
        </xsl:variable>
        <xsl:if test="position() = last() and position() != 1">
            <xsl:text>&amp; </xsl:text>
        </xsl:if>
        <xsl:choose>
            <xsl:when test="substring($firstname,2,1) = '.'">
                <xsl:value-of select="concat(str:tokenize(.,','), ', ')"/>
                <xsl:for-each select="str:tokenize($firstname,'.')">
                    <xsl:value-of select="concat(.,'.')"/>
                    <xsl:if test="position() != last()">
                        <xsl:text> </xsl:text>
                    </xsl:if>
                </xsl:for-each>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="concat(str:tokenize(.,','), ', ')"/>
                <xsl:for-each select="str:tokenize($firstname,' ')">
                    <xsl:value-of select="concat(substring(.,1,1),'.')"/>
                    <xsl:if test="position() != last()">
                        <xsl:text> </xsl:text>
                    </xsl:if>
                </xsl:for-each>
            </xsl:otherwise>
        </xsl:choose>
        <xsl:if test="position() != last()">
            <xsl:text>, </xsl:text>
        </xsl:if>
    </xsl:for-each>
</xsl:template>
<names>
    <author>Lio-Po, Gilda D.</author>
    <author>Cuvin-Aralar, Ma. Lourdes A.</author>
    <author>De la Cruz, Juan C.</author>
    <author>Cruz, E.R.</author>
    <author>Catacutan, M.R.</author>
    <author>De los Santos, M.A.</author>
    <author>Primavera, Jurgenne H.</author>
</names>
Lio-Po, G. D., Cuvin-Aralar, M. L. A., De la Cruz, J. C., Cruz, E. R., Catacutan, M. R., De los Santos, M. A., & Primavera, J. H.