在未指定出现的顺序时处理XSLT中的子标记

时间:2012-04-20 10:23:21

标签: xml xslt xpath xslt-grouping

我正在进行XSLT转换。我有一个源文件,其中有一些名为tag的sometag。

考虑我的源xml是这样的。

<ABC>
    <Name>Some Name </Name>
    <ID>Some ID</ID>
    <Address>Some Address</Address>
    <Place>Some Place</Place>
    <ID>Some ID</ID>
    <Name>Some Name </Name>
    <Name>Some Name </Name>     

</ABC>

规则:

  ABC is parent Tag which has 4 child tags. Name, ID, Address, Place. 
  These child tags can occur many times and in any ordrer.
  Upon reading the tag , I want to change the name of the tag, and do some processing on the value present in the tag.
  The input XML may have child tags in any order, and many times.
  I want to write a common XSLT which will read the child tags in the order in which they occur, and display them as given under.

我想像这样显示输出。

        <Frame:Name>
                   <text>Some Name</text>
        </Frame:Name>
   <Frame:ID>
                   <text>Some ID</text>
        </Frame:ID>
        <Frame:ADdrress>
                   <text>Some Address</text>
        </Frame:Address>
        <Frame:Place>
                   <text>Some Place</text>
        </Frame:Place>
   <Frame:ID>
                   <text>Some ID</text>
        </Frame:ID>
       <Frame:Name>
                   <text>Some Name</text>
        </Frame:Name>
       <Frame:Name>
                   <text>Some Name</text>
        </Frame:Name>

我完全被告知如何做到这一点。

如果源XML中子元素的出现顺序发生变化,它也应该反映在输出XML中。

有人可以分享评论。

谢谢。

2 个答案:

答案 0 :(得分:1)

解决此类问题的XSLT方法是使用模板。结果是更简单,更简短且易于理解的代码,通常没有任何xsl:choosexsl:whenxsl:otherwisexsl:ifxsl:for-each

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

 <xsl:template match="/*">
   <t><xsl:apply-templates/></t>
 </xsl:template>

 <xsl:template match="*/*">
     <xsl:element name="Frame:{name()}" namespace="some:undefined namespace">
       <text><xsl:apply-templates /></text>
     </xsl:element>
 </xsl:template>
</xsl:stylesheet>

在提供的XML文档上应用此转换时

<ABC>
    <Name>Some Name </Name>
    <ID>Some ID</ID>
    <Address>Some Address</Address>
    <Place>Some Place</Place>
    <ID>Some ID</ID>
    <Name>Some Name </Name>
    <Name>Some Name </Name>
</ABC>

产生了想要的正确结果

<t xmlns:Frame="some:undefined namespace">
   <Frame:Name>
      <text>Some Name </text>
   </Frame:Name>
   <Frame:ID>
      <text>Some ID</text>
   </Frame:ID>
   <Frame:Address>
      <text>Some Address</text>
   </Frame:Address>
   <Frame:Place>
      <text>Some Place</text>
   </Frame:Place>
   <Frame:ID>
      <text>Some ID</text>
   </Frame:ID>
   <Frame:Name>
      <text>Some Name </text>
   </Frame:Name>
   <Frame:Name>
      <text>Some Name </text>
   </Frame:Name>
</t>

答案 1 :(得分:0)

根据jeevan的建议。

    

  <xsl:template match="ABC" >
    <ABC>
        <xsl:for-each select ="child::*">
        <xsl:choose>
          <xsl:when test="name()='Name'">
            <xsl:element name="Frame:Name">
              <xsl:apply-templates  select="."/>
           </xsl:element>
          </xsl:when>

          <xsl:when test="name()='ID'">
            <Frame:ID>
              <xsl:apply-templates select="."/>
            </Frame:ID>
          </xsl:when>
            <xsl:when test="name()='Address'">
            <Frame:Address>
              <xsl:apply-templates select="."/>
            </Frame:Address>
          </xsl:when>

          <xsl:when test="name()='Place'">
            <Frame:Place>
              <xsl:apply-templates select="."/>
            </Frame:Place>
          </xsl:when>
     </xsl:choose>
      </xsl:for-each>