我有问题使用XSLT将XML转换为另一个XML

时间:2015-12-25 23:13:20

标签: xml xslt

我是xml的初学者,目前我正致力于使用XSLT将XML转换为另一种XML。但是,我无法弄清楚为什么它现在不起作用。如果你能在这里解释一下这个问题,我会很高兴。

这是我的XMLFile1.xml

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="XSLTFile1.xslt"?>

<School
xmlns="http://www.w3schools.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3schools.com XMLSchema1.xsd">


  <NameOfSchool>FCB</NameOfSchool>

  <Child>

    <FirstName>Sally</FirstName>
    <LastName>Johnson</LastName>
    <P-Number>1008021245</P-Number>


    <Sibling>
      <P-Number>0005052464</P-Number>
      <FirstName>Art</FirstName>
      <LastName>Vandelay</LastName>

    </Sibling>

    <Other>

      <Allergies>No</Allergies>
      <AMS>No</AMS>


    </Other>

  </Child>



  <Parent1>

    <FirstName>H.E</FirstName>
    <LastName>Pennypecker</LastName>
    <P-Number>7806032356</P-Number>
    <Adress>4 Yawkey Way Boston, Massachusetts 02215</Adress>


    <Contact>

      <Phone>
        <Work>0522375796</Work>
        <Home>0522597068</Home>
      </Phone>

    </Contact>


  </Parent1>


  <Parent2>

    <FirstName>Kel</FirstName>
    <LastName>Varnsen</LastName>
    <P-Number>7806089645</P-Number>
    <Adress>1 East 161st Street Bronx, New York City, New York 10451</Adress>

    <Contact>

      <Phone>
        <Work>0522596847</Work>
        <Home>0522597068</Home>
      </Phone>

    </Contact>

  </Parent2>


</School>

这是我的XSLTFile1.xslt

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <xsl:output method="html" indent="yes"/>

  <xsl:template match="Parent1">
      <BGI>
        <Parent1>
          <P-Number>
            <xsl:value-of select="P-Number"/>
          </P-Number>
          <FirstName>
            <xsl:value-of select="FirstName"/>
          </FirstName>
          <LastName>
            <xsl:value-of select="LastName"/>
          </LastName>
        </Parent1>

      </BGI>
  </xsl:template>

  <xsl:template match="Parent2">
    <BGI>
      <Parent2>
        <P-Number>
          <xsl:value-of select="P-Number"/>
        </P-Number>
        <FirstName>
          <xsl:value-of select="FirstName"/>
        </FirstName>
        <LastName>
          <xsl:value-of select="LastName"/>
        </LastName>
      </Parent2>

    </BGI>
  </xsl:template>
</xsl:stylesheet>

我想要的是新的XML文档如下所示:

<BGI>
  <Parent1>
    <P-Number>7806032356</P-Number>
    <FirstName>H.E</FirstName>
    <LastName>Pennypecker</LastName>
  <Parent1>

   <Parent2>
    <P-Number>7806089645</P-Number>
    <FirstName>Kel</FirstName>
    <LastName>Varnsen</LastName>
  <Parent2>
</BGI>

2 个答案:

答案 0 :(得分:0)

您只能写信给<Parent1><Parent2>模板。您没有写入<NameOfSchool><Child>模板(其他兄弟姐妹)。结果,它们在输出中呈现完全相同。如果要删除后面的节点,请编写一个空模板,如下所示。

具体而言,Identity Transform按原样复制所有内容,空模板删除这些引用的节点。我使用管道分隔符(|)来应用引用集合的并集。命名空间doc在XSLT中声明,纯粹是一个任意选择的名称,因为在<School>开始标记的XML文档中有一个未声明的命名空间。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                              xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                              xmlns:doc="http://www.w3schools.com"
                              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                              xsi:schemaLocation="http://www.w3schools.com XMLSchema1.xsd"
                              exclude-result-prefixes="msxsl doc">
<xsl:output method="html" indent="yes"/>
<xsl:strip-space elements="*"/>

  <!-- Identity Transform -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- Empty template to remove nodes -->
  <xsl:template match="doc:NameOfSchool|doc:Child"/>

  <!-- Rewrite of needed nodes, doc/value-of/local-name all used to handle namespace -->
  <xsl:template match="doc:Parent1|doc:Parent2">
    <BGI>
      <xsl:element name='{local-name()}'>
        <P-Number><xsl:value-of select="doc:P-Number"/></P-Number>
        <FirstName><xsl:value-of select="doc:FirstName"/></FirstName>
        <LastName><xsl:value-of select="doc:LastName"/></LastName>
      </xsl:element>
    </BGI>
  </xsl:template>  

</xsl:stylesheet>

顺便说一句,在浏览器中查看此xml时,将应用样式表,但原始XML内容将显示在页面源中。并且因为最终输出的XML不包含任何HTML标记(<div>, <table>, <p>, <span>),所以只会出现值。

答案 1 :(得分:0)

使用以下样式表可以实现预期结果:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="http://www.w3schools.com"
exclude-result-prefixes="ns1">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/ns1:School">
    <BGI>
        <xsl:apply-templates select="ns1:Parent1 | ns1:Parent2"/>
    </BGI>
</xsl:template>

<xsl:template match="ns1:Parent1 | ns1:Parent2">
    <xsl:element name='{local-name()}'>
        <xsl:apply-templates select="ns1:P-Number | ns1:FirstName | ns1:LastName"/>
    </xsl:element>
</xsl:template>

<xsl:template match="*">
    <xsl:element name='{local-name()}'>
        <xsl:value-of select="."/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

注意

  1. 使用前缀来处理源XML中的元素;
  2. 使用xsl:element代替xsl:copy重新创建。{ “无”命名空间中的“复制”元素。