将名称空间添加到其子项中具有名称空间的xml,并通过xslt在其上添加新元素

时间:2014-05-05 19:08:29

标签: xml xslt namespaces

我的输入xml如下所示

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<L1>
    <L2>
        <l3>
            <item>
                <State>1</state>
                <currency>
                    <value1 xmlns:xs="www.anotherexample.com">5</value1>
                    <value2 xmlns:xs="www.anotherexample.com">dd</value2>
                </currency>
            </item>
            <item2>
                <a>1</a>
                <b>2</b>
                <c>3</c>
             </item2>
             <item3>
                 <e>2</e>
                 <l>3</l>
                 <m>3</m>
            </item3>
            <item4>
                 <n>r</n>
                 <p>5</p>
            </item4>
        </l3>
     </L2>
</L1>

我有两个要求

1)xml必须添加一个信封,即另一个xml将位于整个xml的顶部,结果应该看起来像

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>

    <start>
       <a></a>
        .....
        ..... 
       <Body>
       <Envelope>
           <L1>
               <L2>
                   <l3>
                       <item>
                           <State>1</state>
                           <currency>
                               <value1 xmlns:xs="www.anotherexample.com">5</value1>
                               <value2 xmlns:xs="www.anotherexample.com">ca</value2>
                            </currency>
                        </item>
                        <item2>
                              <a>1</a>
                              <b>2</b>
                              <c>3</c>
                         </item2>
                         <item3>
                              <e>2</e>
                              <l>3</l>
                               <m>3</m>
                          </item3>
                          <item4>
                               <n>r</n>
                               <p>5</p>
                          </item4>
                    </l3>
                </L2>
             </L1>
      </Envelope>   
      </Body>
       .....
       ..... 
    </start> 

2第二个要求是原始xml的根标签,即L1标签应该添加一个名称空间,以便根标签变为

    <start>
       <a></a>
        .....
        ..... 
       <Body>
           <Envelope>    
              <L1 xmlns="www.example.com">
                  <L2>
                     <l3>
                        <item>
                           <State>1</state>
                           <currency>
                                 <value1  xmlns:xs="www.anotherexample.com">5</value1>
                                 <value2   xmlns:xs="www.anotherexample.com">ca</value2>
                            </currency>
                </item>
                        <item2>
                             <a>1</a>
                             <c>3</c>
                        </item2>
                        <item3>
                             <e>2</e>
                        </item3>
                        <item4>
                            <n>r</n>
                        </item4>
                   </l3>
                </L2>
             </L1>
        </Envelope>
      </Body>
    </start>

我们如何设计一个xslt来进行这种转换组合。我搜索并找到了为根标签添加命名空间的解决方案,但我如何同时实现这两个结果

注意:输入xml中有许多元素将被使用调用模板忽略或处理,因此在这种情况下直接复制xml和添加命名空间失败

示例:我可能只想输出xml中的输入中的1个标记。编辑原始帖子以显示原始输入xml不打算像输出那样被复制,如新输出所示,输出xml将随输入XML变化,缺少多个标签,顺序为标签必须是常量 对不起以前的不完整描述

1 个答案:

答案 0 :(得分:1)

  

第二个要求是原始xml的根标签即   L1标签应该添加一个名称空间

这并不能准确描述您显示的内容:所有作为根后代的元素会继承根的命名空间 - 因此您需要添加每个新的名称空间:

XSLT 1.0

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

<xsl:template match="/">
    <start>
        <a></a>
        <!-- ... -->
        <Body>
            <Envelope> 
                <xsl:apply-templates select="*" />
            </Envelope>
        </Body>
    </start>
</xsl:template>

<xsl:template match="*">
    <xsl:element name="{local-name()}" namespace="www.example.com">
        <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
</xsl:template>

<xsl:template match="@*">
    <xsl:copy/>
</xsl:template>

</xsl:stylesheet>

将上述样式表应用于更正后的输入:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 
<L1>
  <L2>
    <l3>
      <item>
        <state>1</state>
        <currency>LEVEL</currency> 
            <value1 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">5</value1>
            <value2 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">ca</value2>
      </item>
    </l3>
  </L2>
</L1>

结果是:

<?xml version="1.0" encoding="UTF-8"?>
<start>
   <a/>
   <Body>
      <Envelope>
         <L1 xmlns="www.example.com">
            <L2>
               <l3>
                  <item>
                     <state>1</state>
                     <currency>LEVEL</currency>
                     <value1 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">5</value1>
                     <value2 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">ca</value2>
                  </item>
               </l3>
            </L2>
         </L1>
      </Envelope>
   </Body>
</start>

修改

如果要从输出中删除某些节点,请为它们创建一个特定模板并将其留空。例如,使用以下输入:

<L1>
    <L2>
        <l3>
            <item>
                <state>1</state>
                <currency>
                    <value1 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">5</value1>
                    <value2 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">ca</value2>
                </currency>
            </item>
            <item2>
                <a>1</a>
                <b>2</b>
                <c>3</c>
             </item2>
             <item3>
                 <e>2</e>
                 <l>3</l>
                 <m>3</m>
            </item3>
            <item4>
                 <n>r</n>
                 <p>5</p>
            </item4>
        </l3>
     </L2>
</L1>

我们会将元素<b<l><m><p>的空模板添加到我们之前的样式表中:

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

<xsl:template match="/">
    <start>
        <a></a>
        <!-- ... -->
        <Body>
            <Envelope> 
                <xsl:apply-templates select="*" />
            </Envelope>
        </Body>
    </start>
</xsl:template>

<xsl:template match="*">
    <xsl:element name="{local-name()}" namespace="www.example.com">
        <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
</xsl:template>

<xsl:template match="@*">
    <xsl:copy/>
</xsl:template>

<xsl:template match="b|l|m|p"/>

</xsl:stylesheet>

并获得以下结果:

<?xml version="1.0" encoding="UTF-8"?>
<start>
   <a/>
   <Body>
      <Envelope>
         <L1 xmlns="www.example.com">
            <L2>
               <l3>
                  <item>
                     <state>1</state>
                     <currency>
                        <value1 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">5</value1>
                        <value2 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">ca</value2>
                     </currency>
                  </item>
                  <item2>
                     <a>1</a>
                     <c>3</c>
                  </item2>
                  <item3>
                     <e>2</e>
                  </item3>
                  <item4>
                     <n>r</n>
                  </item4>
               </l3>
            </L2>
         </L1>
      </Envelope>
   </Body>
</start>