如何检查前一个节点是注释还是XML节点?

3

我有类似以下的xml(实际上数据集要大得多):

 <people>
<!-- People start here -->
        <person>
        <name>Sara</name>
        <age>27</age>
        </person>
 <person>
        <name>Carl</name>
        <age>25</age>
        </person>
<!-- Nick is the father -->
    <person>
        <name>Nick</name>
        <age>52</age>
        </person>
</people>

我已经编写了一个XSL来给所有人添加一行,想象一下现在的人员应该是这样的:
<person>
<name>Sara</name>
<age>27</age>
<gender>female</gender>
</person>

然而我仍想保留评论,但有些评论位于结束节点之后,有些则不是。我尝试了很多方法,但不知道如何检查前一个节点是否为注释。以下任何一种方法都没有成功:
  • preceding-sibling::comment()[1](如果有一个注释,它总会得到这个)
  • preceding-sibling::*(无法获取注释)
  • preceding::*(无法获取注释)
我需要查看前一个节点并检查它是否为类型 case,如果是,则继续,否则抓取评论并输出。也许我必须计算整个文档中的节点位置(如何?),然后以这种方式检查前一个节点?这不一定高效。谢谢。

感谢James(http://stackoverflow.com/users/27206/james-gregory)的发现。https://dev59.com/uk7Sa4cB1Zd3GeqP2Efp#2991403 完美解决 :) 谢谢大家! - Sara
Sara,最好的解决方案是覆盖身份模板-这正是thesimm所提出的。如果您阅读有关身份规则的内容并在可能的情况下随处使用它,那么您将从掌握XSLT中受益匪浅。这是最基本的XSLT设计模式之一。有关此设计模式的更多信息,请访问此处:http://www.dpawson.co.uk/xsl/sect2/identity.html。总之,我建议您接受@thesimm的答案。 - Dimitre Novatchev
3个回答

2
像这样的东西可以保留您的 XML 片段中的注释:
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="person">
    <xsl:copy>
        <xsl:copy-of select="."/>
        <gender>gender goes here</gender>
    </xsl:copy>
</xsl:template>

0

这个模板应该复制所有的处理指令,包括注释。

<xsl:template match="processing-instruction()">
    <xsl:copy/>
</xsl:template>

-1
我已经有一段时间没有做XSLT相关的工作了,但是你能否只是做这个?
<xsl:if test="preceding-sibling::comment()[1]">
  <comment>
    <xsl:value-of select="preceding-sibling::comment()[1]" />
  </comment>
</xsl:if>

似乎在http://www.xsltcake.com/上能运行,但会使评论出现两次。

这个不起作用,因为如果曾经有过一条评论,它每次都会通过测试。 - Sara
<xsl:template match="person"> <xsl:copy-of select="preceding-sibling::comment()[count(following-sibling::*[1]|current()) = 1]"/> </xsl:template>这种方法可能有效吗? - Sarkie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接