如果XSLT不存在头部和底部,则添加头部和底部

3

如果输入的XML中不存在指定的父节点,我该如何使用XSLT让其包含在一个父节点中呢?

例如,如果我的输入是:

<Project>...</Project>

我希望你能帮我在前缀和后缀中包装它:

要翻译的内容:

<?xml version "1.0" encoding="utf-8">
<Site>
  <Project>...</Project>
</Site>

如果 <Project> 不是输入的根节点,那么我希望输入内容不做修改。谢谢!

好问题(+1)。请查看我的答案,其中包含完整且简单的解决方案。 - Dimitre Novatchev
XSLT可能不是解决这个特定问题的最佳方案;XSLT基本上是根据现有文档和样式表生成一个全新的XML文档,但在这种情况下,简单地操作现有文档可能更可取;我知道在C#中,从当前子节点中删除节点、放置一个<Site>标签,并将其重新添加为新元素的子节点会相当容易。 - Flynn1179
我理解关于通过其他方式更容易的评论。该应用程序已经部署了各种转换以升级旧的或有问题的输入。 - Mykro
3个回答

4
这个样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="@*|node()" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="/Project">
        <Site>
            <xsl:call-template name="identity"/>
        </Site>
    </xsl:template>
</xsl:stylesheet>

输入1:

<Project>...</Project>

输出 1:

<Site>
    <Project>...</Project>
</Site>

输入2:

<Root>
    <Project>...</Project>
</Root>

输出2:

<Root>
    <Project>...</Project>
</Root>

注意:身份转换。模式匹配。


@DJC:欢迎!随时提问。 - user357812

1

这个转换

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*" name="identity">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="*[not(self::site)]/Project">
  <site>
    <xsl:call-template name="identity"/>
  </site>
 </xsl:template>
</xsl:stylesheet>

仅在元素<Project>不是<site>元素的子元素时,对其进行包装。

应用于此XML文档时:

<t>
  <Project>x</Project>
    <site>
      <Project>y</Project>
    </site>
</t>

正确,期望的结果已生成

<t>
   <site>
      <Project>x</Project>
   </site>
   <site>
      <Project>y</Project>
   </site>
</t>

从问题来看:“<Project>不是输入的根节点,我希望输入保持不变”。 - user357812
一个对我的工具箱很有用的答案,特别是不匹配的部分,谢谢! - Mykro

0
如果您只需要添加前缀和后缀,那么可以寻找其他类Unix的选项,例如grep,它可以更简单地完成此操作。 如果您想在XSL中执行此操作,则应使用xsl:when。
<xsl:template match="/">
         <xsl:choose>       <!-- If Node Period exists add the text -->         <xsl:when test="Period">
                        <xsl:text><Site></xsl:text>
                        <xsl:text>&#xa;</xsl:text>
                        <xsl:text><Site></xsl:text>
            </xsl:when>     </xsl:choose>   <xsl:apply-templates select="Notification"/> </xsl:template>

谢谢你的回答。我尝试了很多次,但是还是无法让它正常工作,非常抱歉。 - Mykro

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