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

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

最佳答案

the second requirment is that the root tag of the original xml ie the L1 tag should have a namespace added to it



这不是您显示的输出内容的准确描述:全部 根的后代元素继承根的命名空间 - 因此您需要将新命名空间添加到每个元素中:

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>

关于xml - 将命名空间添加到在其子项中具有命名空间的 xml,并通过 xslt 在其顶部添加新元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23479917/

相关文章:

c# - CS0234 : The type or namespace name '<namespace2>' does not exist in the namespace '<namespace1>.' (are you missing an assembly reference? )

c++ - 为什么 C++11 不支持这样的名称查找?

namespaces - socket.io 中的命名空间将不起作用

android - textAlignment 不能与 supportsRtl false 一起使用

xml - 从 xsd 架构引用 spring bean 值

content-management-system - 使用 XSL 列出 Sitecore CMS 中项目的所有字段

validation - xslt:检查变量是否不为空

xml - XML 模式中的数字 ID 类型

javascript - 如何通过 JavaScript 在 JSON 中构建此 XML 结构?

java - XPath 检查属性并显示值