XSL - 复杂类型的转换

时间:2013-11-14 23:05:27

标签: xml xslt

我正在尝试编写一个通用的XSLT,它应该转换一个非常复杂的xml文件。 xml文件有许多复杂类型的元素,其中一些元素是可重复的。 。在这个简化的例子中,根元素“data”有两个复杂的元素(“info”和“contact”) 我复制了一个简化的例子:

         <?xml version="1.0" encoding="UTF-8"?>
         <?xml-stylesheet type="text/xsl" href="MyList.xslt"?>
      <data>

            <Info>
                <reportInfo>
                    <reportId>
                        <Number>1</Number>
                    </reportId>
                    <reportType>
                        <code>7</code>
                        <text>Main</text>
                    </reportType>
                    <product>
                        <code>3</code>
                        <text>myProduct</text>
                    </product>
                    <change>
                    <code>0</code>
                    </change>
                    <language>EN</language>
                    <Date>2013-09-25</Date>
                </reportInfo>
                <requestInfo>
            <customerReference>sample_Reference</customerReference>
                    <requestType>
                        <code>53</code>
                        <text>Onlineanfrage</text>
                    </requestType>
                    <Address>
                      <postBox>
                        <postBoxNumber>1</postBoxNumber>
                        <postalCode>123</postalCode>
                        <city>abcd</city>
                      </postBox>
                      <postBox>
                        <postBoxNumber>2</postBoxNumber>
                        <postalCode>456</postalCode>
                        <city>efgh</city>
                      </postBox>
                    </Address>
                </requestInfo>
            </Info>
            <contact>
               <Address>
                    <name>
                        <fullname>firstname surename</fullname>
                    </name>
                    <post>
                        <street>mystreet</street>
                        <postalCode>9876</postalCode>
                        <city>mycity</city>
                        <country>
                            <code>110</code>
                            <text>mycountry</text>
                        </country>
                    </post>
                    <othercontacts type="PHONE">123456</othercontacts>
                    <othercontacts type="FAX">123457</othercontacts>
                    <othercontacts type="EMAIL">email@email.com</othercontacts>
                </Address>
            </contact>

      </data>

我正在寻找以下结果(试图给出一个样本)在哪里 - ( text1 )始终是根元素下第一个复杂元素的name()(例如联系人) - ( text2 )始终是实际节点的父节点(例如帖子) - ( text3 )是实际节点的name()(例如street / postalCode) - ()是text3 / actual节点的值(例如mystreet / 9876)。 但是,在某些节​​点(例如联系中的其他接触)中,要求是 - ( text1 )始终是根元素下第一个复杂元素的name()(例如联系人) - ( text2 )始终是实际节点(例如其他合同) - ( text3 )应为“type”(例如PHONE) - ()是“othercontract”的值(例如123456)

    <MyList>
    <list>
    <text1>info</text1>
    <text2>reportId</text2>
    <text3>Number</text3>
    <Value>1</Value>
</list>
<list>
    <text1>info</text1>
    <text2>reportType</text2>
    <text3>code</text3>
    <Value>7</Value>
</list>
<list>
    <text1>info</text1>
    <text2>reportType</text2>
    <text3>text</text3>
    <Value>Main</Value>
</list>
..........
...........
    <list>
    <text1>info</text1>
    <text2>postBox</text2>
    <text3>postBoxNumber</text3>
    <Value>1</Value>
</list> 
<list>
    <text1>info</text1>
    <text2>postBox</text2>
    <text3>postalCode</text3>
    <Value>123</Value>
</list>
<list>
    <text1>info</text1>
    <text2>postBox</text2>
    <text3>city</text3>
    <Value>abcd</Value>
</list>
......
.......

<list>
    <text1>contact</text1>
    <text2>name</text2>
    <text3>fullname</text3>
    <Value>firstname surename</Value>
</list>
<list>
    <text1>contact</text1>
    <text2>post</text2>
    <text3>street</text3>
    <Value>mystreet</Value>
</list>
<list>
    <text1>contact</text1>
    <text2>post</text2>
    <text3>postalCode</text3>
    <Value>9876</Value>
</list>
<list>
    <text1>contact</text1>
    <text2>post</text2>
    <text3>city</text3>
    <Value>mycity</Value>
</list>
..........
...........
<list>
    <text1>contact</text1>
    <text2>othercontacts</text2>
    <text3>PHONE</text3>
    <Value>123456</Value>
</list>
<list>
    <text1>contact</text1>
    <text2>othercontacts</text2>
    <text3>FAX</text3>
    <Value>123457</Value>
</list>
    </MyList>

我试过以下但我遇到的问题很少:

1) - 我试图用“if”过滤“list”的结果,只有这样才能转换带有值的元素,但我也得到了“list”元素,它们不包含“text3”和“价值“元素。我试图用空模板删除它们没有任何成功。

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes"/>

      <xsl:template match="/">
          <MyList>
          </xsl:for-each> 
          <xsl:for-each select="//data">
    <!-- selecting all nodes-->
              <xsl:for-each select="descendant::node()">
                  <list>
                       <text1><xsl:value-of select="name(parent::node())"/></text1>
                       <text2><xsl:value-of select="local-name(parent::node()[position()])"/></text2>

            <!-- tried to get only elements that does have a value of type text() -->
                       <xsl:if test="text() &gt;0" >
                       <text3><xsl:value-of select="name(.)"/></text3>
                       <Value><xsl:value-of select="."/></Value>
                       </xsl:if>
                 </list>
                 </xsl:for-each>
          </xsl:for-each> 
          </MyList>
     </xsl:template>

<!-- tried to delete nodes that do not have element text3 -->
<xsl:template match="list[not(text3)]"/>           
     </xsl:stylesheet>

我期待着你的回复。提前致谢

1 个答案:

答案 0 :(得分:1)

这应该有效(根据评论中的标准进行编辑):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <MyList>
        <xsl:apply-templates select="//*[text()!='']"/>
    </MyList>
  </xsl:template>
  <xsl:template match="*[count(@type)=0]">
        <list>
            <xsl:variable name="p" select="count(ancestor::*)-1"/>
            <text1>
                <xsl:value-of select="name(ancestor::*[$p])"/>
            </text1>
            <text2>
                <xsl:value-of select="name(..)"/>
            </text2>
            <text3>
                <xsl:value-of select="name()"/>
            </text3>
            <Value>
                <xsl:value-of select="text()"/>
            </Value>
        </list>
  </xsl:template>
  <xsl:template match="*[count(@type)!=0]">
        <list>
            <xsl:variable name="p" select="count(ancestor::*)-1"/>
            <text1>
                <xsl:value-of select="name(ancestor::*[$p])"/>
            </text1>
            <text2>
                <xsl:value-of select="name()"/>
            </text2>
            <text3>
                <xsl:value-of select="@type"/>
            </text3>
            <Value>
                <xsl:value-of select="text()"/>
            </Value>
        </list>
  </xsl:template>
</xsl:stylesheet>

当应用于您的输入时,XML会给出:

<MyList>
    <list>
        <text1>Info</text1>
        <text2>reportId</text2>
        <text3>Number</text3>
        <Value>1</Value>
    </list>
    <list>
        <text1>Info</text1>
        <text2>reportType</text2>
        <text3>code</text3>
        <Value>7</Value>
    </list>
    <list>
        <text1>Info</text1>
        <text2>reportType</text2>
        <text3>text</text3>
        <Value>Main</Value>
    </list>
    <list>
        <text1>Info</text1>
        <text2>product</text2>
        <text3>code</text3>
        <Value>3</Value>
    </list>
    <list>
        <text1>Info</text1>
        <text2>product</text2>
        <text3>text</text3>
        <Value>myProduct</Value>
    </list>
    <list>
        <text1>Info</text1>
        <text2>change</text2>
        <text3>code</text3>
        <Value>0</Value>
    </list>
    <list>
        <text1>Info</text1>
        <text2>reportInfo</text2>
        <text3>language</text3>
        <Value>EN</Value>
    </list>
    <list>
        <text1>Info</text1>
        <text2>reportInfo</text2>
        <text3>Date</text3>
        <Value>2013-09-25</Value>
    </list>
    <list>
        <text1>Info</text1>
        <text2>requestInfo</text2>
        <text3>customerReference</text3>
        <Value>sample_Reference</Value>
    </list>
    <list>
        <text1>Info</text1>
        <text2>requestType</text2>
        <text3>code</text3>
        <Value>53</Value>
    </list>
    <list>
        <text1>Info</text1>
        <text2>requestType</text2>
        <text3>text</text3>
        <Value>Onlineanfrage</Value>
    </list>
    <list>
        <text1>Info</text1>
        <text2>postBox</text2>
        <text3>postBoxNumber</text3>
        <Value>1</Value>
    </list>
    <list>
        <text1>Info</text1>
        <text2>postBox</text2>
        <text3>postalCode</text3>
        <Value>123</Value>
    </list>
    <list>
        <text1>Info</text1>
        <text2>postBox</text2>
        <text3>city</text3>
        <Value>abcd</Value>
    </list>
    <list>
        <text1>Info</text1>
        <text2>postBox</text2>
        <text3>postBoxNumber</text3>
        <Value>2</Value>
    </list>
    <list>
        <text1>Info</text1>
        <text2>postBox</text2>
        <text3>postalCode</text3>
        <Value>456</Value>
    </list>
    <list>
        <text1>Info</text1>
        <text2>postBox</text2>
        <text3>city</text3>
        <Value>efgh</Value>
    </list>
    <list>
        <text1>contact</text1>
        <text2>name</text2>
        <text3>fullname</text3>
        <Value>firstname surename</Value>
    </list>
    <list>
        <text1>contact</text1>
        <text2>post</text2>
        <text3>street</text3>
        <Value>mystreet</Value>
    </list>
    <list>
        <text1>contact</text1>
        <text2>post</text2>
        <text3>postalCode</text3>
        <Value>9876</Value>
    </list>
    <list>
        <text1>contact</text1>
        <text2>post</text2>
        <text3>city</text3>
        <Value>mycity</Value>
    </list>
    <list>
        <text1>contact</text1>
        <text2>country</text2>
        <text3>code</text3>
        <Value>110</Value>
    </list>
    <list>
        <text1>contact</text1>
        <text2>country</text2>
        <text3>text</text3>
        <Value>mycountry</Value>
    </list>
    <list>
        <text1>contact</text1>
        <text2>othercontacts</text2>
        <text3>PHONE</text3>
        <Value>123456</Value>
    </list>
    <list>
        <text1>contact</text1>
        <text2>othercontacts</text2>
        <text3>FAX</text3>
        <Value>123457</Value>
    </list>
    <list>
        <text1>contact</text1>
        <text2>othercontacts</text2>
        <text3>EMAIL</text3>
        <Value>email@email.com</Value>
    </list>
</MyList>