节点的所有子节点都出现在输出中的同一行上

时间:2015-03-31 10:09:58

标签: xml xslt

我有一些看起来像这样的XML:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE article PUBLIC "-//NLM//DTD Journal Publishing DTD v2.3 20070202//EN"
"http://dtd.nlm.nih.gov/publishing/2.3/journalpublishing.dtd"><article>
<front>
<!-- Some metadata -->
</front>
<body>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In vel metus felis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas <italic>habitasse</italic> venenatis.</p>
<!-- More elements -->
</body>
<back>
<ref-list>
<ref id="id-28299"><nlm-citation citation-type="journal">
<person-group person-group-type="author"><name><surname>Bar</surname>
<given-names>F</given-names>
</name>
</person-group>
<article-title>Baz</article-title>
<source>Made up</source>
<year>1970</year>
<volume>27</volume>
<issue>(4)</issue>
<fpage>3</fpage>
<lpage>7</lpage>
<pub-id pub-id-type="doi">http://some.url.org</pub-id>
</nlm-citation>
</ref>
<!-- More ref entries -->
</ref-list>
</back>
</article>

我需要对其进行转换,以使ref元素(以及 ref元素,其他所有内容必须保持原样)分别包含在一行中,元素之间有空格。即。

<ref id="id-28299"><nlm-citation citation-type="journal"> <person-group person-group-type="author"><name><surname>Bar</surname> <given-names>F</given-names></name></person-group> <article-title>Baz</article-title> <source>Made up</source> <year>1970</year> <volume>27</volume> <issue>(4)</issue> <fpage>3</fpage> <lpage>7</lpage> <pub-id pub-id-type="doi">http://some.url.org</pub-id></nlm-citation></ref>

我可以通过使用此样式表展开元素来实现:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xlink="http://www.w3.org/1999/xlink">

<xsl:output method="xml" indent="yes"/>

<xsl:template match="*">
    <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

<xsl:template match="ref//*">
    <xsl:apply-templates/><xsl:if test="following-sibling::*"><xsl:text> </xsl:text></xsl:if>
</xsl:template>

</xsl:stylesheet>

但我想要保留标签。所以我尝试了以下内容:

<xsl:template match="ref//*">
    <xsl:element name="{local-name()}"><xsl:apply-templates/></xsl:element><xsl:if test="following-sibling::*"><xsl:text> </xsl:text></xsl:if>
</xsl:template>

但现在每个元素都会出现在不同的行上。我也尝试过使用<xsl:strip-space>,但这似乎根本没有改变输出。

2 个答案:

答案 0 :(得分:1)

您可以尝试将“缩进”选项设置为“否”,然后使用strip-space而不是从输入XML中删除所有空格,而是使用特定模板来忽略仅空白节点在ref下。这样可以防止它们被默认模板输出。

试试这个XSLT:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xlink="http://www.w3.org/1999/xlink">

<xsl:output method="xml" indent="no"/>

<xsl:template match="*">
    <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

<xsl:template match="ref//*">
    <xsl:element name="{local-name()}"><xsl:apply-templates/></xsl:element><xsl:if test="following-sibling::*"><xsl:text> </xsl:text></xsl:if>
</xsl:template>

<xsl:template match="ref//text()[not(normalize-space())]" />

</xsl:stylesheet>

答案 1 :(得分:0)

XSLT 3.0(和Saxon)有<xsl:output method="xml" indent="yes" suppress-indentation="ref"/>,专为此目的而设计。如果你不能利用它,我建议使用indent =&#34; no&#34;,并在ref元素之间(以及你想要它的任何其他地方)添加空格&#34;手工&#34;使用xsl:value-of或xsl:text。