2012-10-26 88 views
1

我有一个XML文件转换为XML使用XSLT的问题。 我似乎可以得到的第一个节点,但母鸡我不能让节点命名,其属性和价值的attribues,并在某些情况下,节点有一个节点名为至极具有属性和值,我需要: 下面是一个例子文件(编辑:空格添加legiblity):的XML xml的使用XSLT与节点具有相同名称的

<?xml version='1.0' encoding='UTF-8'?> 
<arb:result xmlns:arb="urn::codeservice"> 
<arb:document 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="urn::codeservice prod_code.xsd"> 
    <header>Produced by CodeRows 4.2</header> 
    <body> 
    <termsystem id="1" begindate="1970-01-01T00:00:01" 
     expirationdate="2099-12-31T23:59:59" 
     lastmodifieddate="2012-10-05T09:52:02.35522" 
     lastmodifiedby="Admin"> 
    <attribute type="longname" datatype="ST" 
     language="fi">1</attribute> 
    <attribute type="status" datatype="ST">1</attribute> 
    <attribute type="codetype" datatype="ST">1</attribute> 
    <attribute type="relatesto" datatype="ST">BASE</attribute> 
    <attribute type="relatestoname" datatype="ST">BASE</attribute> 
    <attribute type="hierarchical" datatype="ST">0</attribute> 
    <termitementry id="1010110" language="fi" 
     createdate="2007-10-25T15:24:17.0" 
     begindate="2003-01-01T00:00:01.0" 
     expirationdate="2004-12-31T23:59:59.0" 
     lastmodifieddate="2007-10-25T17:06:25.0" 
     lastmodifiedby="Admin"> 
    <attribute type="status" datatype="ST">1</attribute> 
    <attribute type="shortname" datatype="ST" language="fi">Whey protein</attribute> 
    <attribute type="longname" datatype="ST" language="fi" /> 
    <attribute type="abbreviation" datatype="ST" 
     language="fi">Raspberry</attribute> 
    <attribute type="hierarchylevel" datatype="ST">0</attribute> 
    <attribute type="parentid" datatype="ST" language="fi" /> 
    <attribute type="description" datatype="ST" language="fi" /> 
    <attribute type="owner" datatype="ST" 
     language="sv">Admin</attribute> 
    <attribute type="externallink" 
     datatype="CV" 
     begindate="2003-01-01T00:00:01.0" 
     expirationdate="2005-12-31T23:59:59.0" 
     ><codedvalue code="08" 
      codesystem="PUN" 
      codesystemversion="1" 
      referenceid="BASEpowder" /></attribute> 
    <attribute type="externallink" 
     datatype="CV" 
     begindate="2001-01-01T00:00:01.0" 
     expirationdate="2006-12-31T23:59:59.0" 
     ><codedvalue code="80112" 
      codesystem="PROTEIN" 
      codesystemversion="1" 
      referenceid="BASEprotein" /></attribute> 
    <attribute type="externallink" 
     datatype="CV" 
     begindate="2003-01-01T00:00:01.0" 
     expirationdate="2008-01-31T23:59:59.0" 
     ><codedvalue code="03" 
      codesystem="REF" 
      codesystemversion="1" 
      referenceid="BASEref" /></attribute> 
</termitementry 
></termsystem 
></body 
></arb:document 
></arb:result> 

我使用的XSLT是:

<?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" indent="yes"/> 

    <xsl:template match="termitementry"> 
     <xsl:element name="CodeRow"> 

      <xsl:element name="Code"> 
       <xsl:apply-templates select="@id" /> 
      </xsl:element> 

      <xsl:element name="Begindate"> 
       <xsl:apply-templates select="@begindate" /> 
      </xsl:element> 

      <xsl:element name="Expirationdate"> 
        <xsl:apply-templates select="@expirationdate" /> 
      </xsl:element> 

      <xsl:element name="Lastmodifiedby"> 
        <xsl:apply-templates select="@lastmodifiedby" /> 
      </xsl:element> 


     </xsl:element> 
    </xsl:template> 

    <xsl:template match="@id"> 
     <xsl:value-of select="." /> 
    </xsl:template> 

    <xsl:template match="@begindate"> 
     <xsl:value-of select="." /> 
    </xsl:template> 

    <xsl:template match="@expirationdate"> 
     <xsl:value-of select="." /> 
    </xsl:template> 

    <xsl:template match="@lastmodifiedby"> 
     <xsl:value-of select="." /> 
    </xsl:template> 

</xsl:stylesheet> 

,并用这个,我似乎只得到第一个节点后的属性,但没有什么+我得到一些废话,我正在使用http://chris.photobooks.com/xml/default.htm来测试东西

<transformiix:result> 
    Produced by CodeRows 4.2 


    1 
    1 
    1 
    BASE 
    BASE 
    0 
    <CodeRow> 
     <Code> 
      1010110 
     </Code> 
     <Begindate> 
      2003-01-01T00:00:01.0 
     </Begindate> 
     <Expirationdate> 
      2004-12-31T23:59:59.0 
     </Expirationdate> 
     <Lastmodifiedby> 
      Admin 
     </Lastmodifiedby> 
    </CodeRow> 
</transformiix:result> 

谁能帮如何走出休息吗?

我希望得到一个XML与基本结构:

<coderow> 
    <Code> 
      1010110 
    </Code> 
    <Begindate> 
     2003-01-01 (only want the 10 first digits of 2003-01-01T00:00:01.0, preferably I would just to have the digits so it looks like 20030101) 
    </Begindate> 
    <Shortname> 
     Whey protein 
    </Shortname> 
    <BASEpowder> 
     08 
    <BASEpowder> 
    <BASEprotein> 
     80112 
    </BASEprotein> 

</CodeRow> 

又是如何得出我出去,我不能看到我所做的任何templete它“通过CodeRows 4.2等。公司生产的”?

+2

问题不清楚,请更新输出与输入中的实际值XML。 –

回答

2

在回答你的问题“我怎么会出来'由CodeRows 4.2等生产''我不能看到我为它做了任何模板?”答案是因为你还没有制作任何模板对于其他元素,XSLT将使用默认的模板匹配。此默认行为将处理所有节点的子节点,或者在案例或文本节点中,它会将这些输出为文本。

XSLT将开始我眺望远处为顶级文档元素相匹配的模板,因为你没有指定一个模板匹配,默认行为踢。你第一个模板匹配termitementry并通过它发现它已经执行了所有父元素的默认匹配。

要停止这种情况的发生,并直接跳转到termitemtentry节点,你应该做这样的事情

<xsl:template match="/"> 
    <xsl:apply-templates select="//termitementry" /> 
</xsl:template> 

此外,请注意您的现有代码把属性转换成元素可以简化。相反,这样做

<xsl:element name="Code"> 
    <xsl:apply-templates select="@id" /> 
</xsl:element> 

的你可以做这个

<Code> 
    <xsl:value-of select="@id"/> 
</Code> 

这意味着你可以删除匹配所有属性的模板。

你可能只需要为你的“外部”链接元素,模板匹配,你可以做这样的事情

<xsl:template match="attribute[@type='externallink']"> 
    <xsl:element name="{codedvalue/@referenceid}"> 
     <xsl:value-of select="codedvalue/@code"/> 
    </xsl:element> 
</xsl:template> 

以下是完整的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="/"> 
     <xsl:apply-templates select="//termitementry"/> 
    </xsl:template> 

    <xsl:template match="termitementry"> 
     <CodeRow> 
     <Code> 
      <xsl:value-of select="@id"/> 
     </Code> 
     <Begindate> 
      <xsl:value-of select="@begindate"/> 
     </Begindate> 
     <Expirationdate> 
      <xsl:value-of select="@expirationdate"/> 
     </Expirationdate> 
     <Lastmodifiedby> 
      <xsl:value-of select="@lastmodifiedby"/> 
     </Lastmodifiedby> 
     <xsl:apply-templates select="attribute[@type='externallink']"/> 
     </CodeRow> 
    </xsl:template> 

    <xsl:template match="attribute[@type='externallink']"> 
     <xsl:element name="{codedvalue/@referenceid}"> 
     <xsl:value-of select="codedvalue/@code"/> 
     </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

当适用于您的样品XML,以下是输出

<CodeRow> 
    <Code>1010110</Code> 
    <Begindate>2003-01-01T00:00:01.0</Begindate> 
    <Expirationdate>2004-12-31T23:59:59.0</Expirationdate> 
    <Lastmodifiedby>Admin</Lastmodifiedby> 
    <BASEpowder>08</BASEpowder> 
    <BASEprotein>80112</BASEprotein> 
    <BASEref>03</BASEref> 
</CodeRow> 
+0

我<3 U,我还没有弄清楚xslt paraser是如何处理文档的,直到您解释为止,现在我想知道我是否想分析日期,以便只取出我需要的第一个数字来为它做个模板。想要2003-01-01T00:00:01.0只会是20030101 – Kkloe

+0

这并不难。例如,在XSLT1.0中,可以使用'substring'和'translate'的组合。如果你不能解决这个问题,请随时提出一个关于日期格式的全新问题,我相信它会很快得到回复:) –

+0

还有一件事,即使用哪种XSLT版本,XSLT1.0或XSLT2 .0? – Kkloe

相关问题