请建议 xpath 来检查元素“mo”是否在“mfrac”的第一个子元素中以“文本节点”开头。当前的 XSLT 代码对于所有“mfrac”都成功运行,其中这些代码不应嵌套在另一个“mfrac”中(数学 1 和 2 成功运行,但数学 3 未成功运行)。如果 'mfrac' 被另一个 'mfrac' 嵌套,则会出现一些错误消息。如果“mo”在“mfrac/child::*”中没有前面的文本节点(“mo”作为第一个文本节点),则所需的输出是“mo”应该获取属性“form=prefix”。请建议如何避免出现错误消息。忽略结果文本中的注释。
XML:
<article>
<body>
<p>
<math id="eq1"><mi>i</mi>
<mfrac>
<mrow><mo>+</mo></mrow>
<mrow><mi>t</mi></mrow>
</mfrac>
</math>
<math id="eq2">
<mfrac>
<mrow><mi>i</mi><mo>+</mo></mrow>
<mrow><mi>t</mi></mrow>
</mfrac>
</math>
<math id="eq3"><mi>i</mi><mfrac><mrow><mfrac><mo>+</mo><mi>n</mi></mfrac></mrow><mrow><mi>t</mi></mrow></mfrac></math>
</p>
</body>
</article>
XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
<xsl:template match="mo">
<xsl:choose>
<xsl:when test="string-length(preceding::text()[1]
[normalize-space(.)!='']
[generate-id(ancestor-or-self::*[count(preceding-sibling::*)=0]/parent::*[name()='mfrac'])=generate-id(current()/ancestor-or-self::*[count(preceding-sibling::*)=0]/parent::*[name()='mfrac'])]) eq 0">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:attribute name="form" select="'prefix'"/>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
所需输出:
<article>
<body>
<p>
<mmlmath id="eq1"><mi>i</mi>
<mfrac>
<mrow><mo form="prefix">+</mo></mrow><!--Here prefix attribute required because MO found as first text node within MFRAC's first child-->
<mrow><mi>t</mi></mrow>
</mfrac>
</mmlmath>
<mmlmath id="eq2">
<mfrac>
<mrow><mi>i</mi><mo>+</mo></mrow><!--Here attribute not required because 'MO' is not a first text node-->
<mrow><mi>t</mi></mrow>
</mfrac>
</mmlmath>
<mmlmath id="eq3"><mi>i</mi><mfrac><mrow><mfrac><!--Nested MFRAC--><mo form="prefix">+</mo><!--Attribute required here--><mi>n</mi></mfrac></mrow><mrow><mi>t</mi></mrow></mfrac></mmlmath>
</p>
</body>
</article>
错误消息:
XPTY0004: A sequence of more than one item is not allowed as the first argument of generate-id() (<mfrac/>, <mfrac/>)
最佳答案
您应该能够测试当前的 mo
是否是包含 text()
的第一个祖先 mfrac
的第一个后代> 节点。
希望这是有道理的。 :-)
这是一个应该有所帮助的示例...
XML 输入
<article>
<body>
<p>
<math id="eq1">
<mi>i</mi>
<mfrac>
<mrow>
<mo>+</mo>
</mrow>
<mrow>
<mi>t</mi>
</mrow>
</mfrac>
</math>
<math id="eq2">
<mfrac>
<mrow>
<mi>i</mi>
<mo>+</mo>
</mrow>
<mrow>
<mi>t</mi>
</mrow>
</mfrac>
</math>
<math id="eq3">
<mi>i</mi>
<mfrac>
<mrow>
<mfrac>
<mo>+</mo>
<mi>n</mi>
</mfrac>
</mrow>
<mrow>
<mi>t</mi>
</mrow>
</mfrac>
</math>
</p>
</body>
</article>
XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="mo[. is (ancestor::mfrac[1]//*[text()])[1]]">
<xsl:copy>
<xsl:attribute name="form" select="'prefix'"/>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
XML 输出
<article>
<body>
<p>
<math id="eq1">
<mi>i</mi>
<mfrac>
<mrow>
<mo form="prefix">+</mo>
</mrow>
<mrow>
<mi>t</mi>
</mrow>
</mfrac>
</math>
<math id="eq2">
<mfrac>
<mrow>
<mi>i</mi>
<mo>+</mo>
</mrow>
<mrow>
<mi>t</mi>
</mrow>
</mfrac>
</math>
<math id="eq3">
<mi>i</mi>
<mfrac>
<mrow>
<mfrac>
<mo form="prefix">+</mo>
<mi>n</mi>
</mfrac>
</mrow>
<mrow>
<mi>t</mi>
</mrow>
</mfrac>
</math>
</p>
</body>
</article>
关于xml - 建议 xpath 检查相同类型的嵌套元素中的第一个 'text' 节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32252018/