Xml 使用xslt解析并格式化名称
我正试图编写一个XSLT样式表来处理作者的姓名并创建引用的APA版本。关于作者姓名的APA引文格式:如果引文的第一个要素是姓名,则列出姓名的姓氏,然后是首字母缩写。在最后一位作者之前用逗号和符号(&)分隔名称。我在这篇文章中遵循了Dimitre Novatchev的解决方案:但我没有得到我想要的结果 输入: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
刘波,吉尔达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>& </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>& </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>& </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>& </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.