1

我有以下 XML 结构:

<Main>
    <Node1>Definite</Node1>
    <Node2>Definite</Node2>
    <Node3>Definite</Node3>
    <Node4>Definite</Node4>
    <Node5>Definite</Node5>
    <Node6>Definite</Node6>
    <A>Possible</A>
    <B>Possible</B>
    <C>Possible</C>
    <D>Possible</D>    
    <E>Possible</E>
    <F>Possible</F>
    <G>Possible</G>
    <H>Possible</H>
    <I>Possible</I>
</Main>

节点命名为单个字母,例如。<A>是 XML 结构中可能不存在的节点,而所有其他节点都是确定的。

我需要<ZZZ>在结构中插入节点,以便它始终位于如下所示的位置。

<Main>
    <Node1>Value</Node1>
    <Node2>Value</Node2>
    <Node3>Value</Node3>
    <Node4>Value</Node4>
    <Node5>Value</Node5>
    <Node6>Value</Node6>
    <A>Value</A>
    <B>Value</B>
    <C>Value</C>
    <D>Value</D>    
    <E>Value</E>
    <ZZZ>Value</ZZZ>
    <F>Value</F>
    <G>Value</G>
    <H>Value</H>
    <I>Value</I>
</Main>

所以说节点<E><C><H>存在它会是:

<Main>
    <Node1>Value</Node1>
    <Node2>Value</Node2>
    <Node3>Value</Node3>
    <Node4>Value</Node4>
    <Node5>Value</Node5>
    <Node6>Value</Node6>
    <A>Value</A>
    <B>Value</B>
    <D>Value</D>    
    <ZZZ>Value</ZZZ>
    <F>Value</F>
    <G>Value</G>
    <I>Value</I>
</Main>

希望这解释得足够清楚:)

4

2 回答 2

2

好吧,这取决于需要哪些元素,哪些是可选的!例如,如果你可以说 <F> 是必需的,你可以在 F 元素之前插入 ZZZ 元素:

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

<xsl:template match="F">
    <ZZZ>Value</ZZZ>
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:apply-templates select="node()"/>
    </xsl:copy>
</xsl:template>

如果你不能说,有一个必需的元素,你需要在模板中插入主元素:

<xsl:template match="Main">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:apply-templates select="Node1|Node2|Node3|Node4|Node5|Node6|A|B|C|D|E"/>
        <ZZZ>Value</ZZZ>
        <xsl:apply-templates select="F|G|H|I"/>
    </xsl:copy>
</xsl:template>
于 2012-04-05T10:31:03.167 回答
0

一个更通用的解决方案,可以适应任何动态指定的名称和任何数量的确定或可能的名称

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

 <my:occurences>
    <definites>
        <definite>Node1</definite>
        <definite>Node2</definite>
        <definite>Node3</definite>
        <definite>Node4</definite>
        <definite>Node5</definite>
        <definite>Node6</definite>
    </definites>
    <possibles>
        <possible>A</possible>
        <possible>B</possible>
        <possible>C</possible>
        <possible>D</possible>
        <possible>E</possible>
        <possible>F</possible>
        <possible>G</possible>
        <possible>H</possible>
        <possible>I</possible>
    </possibles>
 </my:occurences>

 <xsl:variable name="vOccurencies" select=
   "document('')/*/my:occurences"/>

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

 <xsl:template match="/*">
  <xsl:copy>
   <xsl:apply-templates select=
    "*[name() =
        ($vOccurencies/definites/definite
        |
         $vOccurencies/possibles/possible
                  [not(position()
                  >
                   string-length(substring-before($vOccurencies/possibles, 'F')))
                   ]
         )
       ]"/>
   <ZZZ>Value</ZZZ>
   <xsl:apply-templates select=
   "*[name()
     =
      $vOccurencies/possibles/possible
                  [position()
                  >
                   string-length(
                      substring-before($vOccurencies/possibles, 'F')
                                )
                   ]
     ]"/>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时

<Main>
    <Node1>Value</Node1>
    <Node2>Value</Node2>
    <Node3>Value</Node3>
    <Node4>Value</Node4>
    <Node5>Value</Node5>
    <Node6>Value</Node6>
    <A>Value</A>
    <B>Value</B>
    <C>Value</C>
    <D>Value</D>
    <E>Value</E>
    <ZZZ>Value</ZZZ>
    <F>Value</F>
    <G>Value</G>
    <H>Value</H>
    <I>Value</I>
</Main>

产生了想要的正确结果

<Main>
   <Node1>Value</Node1>
   <Node2>Value</Node2>
   <Node3>Value</Node3>
   <Node4>Value</Node4>
   <Node5>Value</Node5>
   <Node6>Value</Node6>
   <A>Value</A>
   <B>Value</B>
   <C>Value</C>
   <D>Value</D>
   <E>Value</E>
   <ZZZ>Value</ZZZ>
   <F>Value</F>
   <G>Value</G>
   <H>Value</H>
   <I>Value</I>
</Main>

请注意

在实际情况下,my:occurances元素将位于其单独的 XML 文档中——因此 XSLT 代码没有硬编码的元素名称,并且在发生 xml 文档更改时无需修改。

于 2012-04-05T13:00:08.853 回答