【问题标题】:Adding namespace to a xml having namespaces in its child and also adding new elements through xslt on top of it将名称空间添加到在其子项中具有名称空间的 xml 中,并通过 xslt 在其顶部添加新元素
【发布时间】:2014-05-05 19:08:29
【问题描述】:

我的输入 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 不同,缺少几个标签,顺序为标签必须是恒定的 抱歉之前的描述不完整

【问题讨论】:

  • 确定不是您输入的 XML?它在多个方面都无效。
  • 是的,迈克尔,这不是我的输入 xml,只是我想要完成的主要事情的一小部分
  • "输出 xml 将与输入 XML 不同,缺少几个标签或对其进行了一些操作" 您无法回答这部分问题,因为太模糊了。通常,您需要决定是否希望样式表指定 (a) 要包含在输出中的元素或 (b) 要排除的元素。至于“对它们进行一些操作”,您将需要“一些代码”来完成...
  • 如果我们不考虑操作部分,是否可以留下一些节点,例如我们看到的 item2, item3, item4 并通过 xslt 来满足需要。我已经编辑了问题以使其具体

标签: xml xslt namespaces


【解决方案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>

我们将为元素 &lt;b&lt;l&gt;&lt;m&gt;&lt;p&gt; 添加一个空模板到我们之前的样式表中:

<?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>

【讨论】:

  • 嗨迈克尔,这确实将命名空间添加到我的初始 xml,但我有问题。在我拥有的大 xml 中,我将从输入 xml 的每个子节点中仅选择几个值。我想通过在第一个模板 match = / 中使用调用模板来建立这个,但这会导致元素的重复。解决这个问题的任何想法
  • @user2873194 我建议您发布一个完整的问题:显示整个输入 XML 并准确地说明您要如何修改它。我也看不出“调用模板”与这些有什么关系。
  • @michaelhor257k。我已经编辑了问题并希望清楚地使用问题
  • @michaelhor257k。感谢您的回答,您的回答为我指明了方向
  • 上述转换不会将我的命名空间保留为值 1
猜你喜欢
  • 2013-07-24
  • 2013-04-05
  • 2011-02-10
  • 1970-01-01
  • 2013-04-07
  • 2019-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多