XSLT - 使用动态id来查询其他节点上的信息

时间:2015-03-05 13:13:53

标签: xml xslt dynamic

我被困了一段时间所以你能不能给我一些建议?

我是一个由软件生成的大型XML。它包含以下数据

我想使用hasNote / list / ref节点上的id来使用该id显示Note节点上的信息。实际上,hasnote / list / ref中的id对应于我想在Note节点中访问的id。

我在XSLT中是全新的,所以我编写了类似的东西 XSLT

<?xml version="1.0" encoding="UTF-8" ?>

<xsl:stylesheet version="2.0" exclude-result-prefixes="xs xdt err fn" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:fn="http://www.w3.org/2005/xpath-functions" 
    xmlns:xdt="http://www.w3.org/2005/xpath-datatypes"
    xmlns:err="http://www.w3.org/2005/xqt-errors">
<xsl:output method="text" indent="no" omit-xml-declaration="yes"/>
<xsl:template match="/archive">
<xsl:text>"Name","Description","RuleType","Active","Threshold","ID","VersionID","Alias","#childOf","#dependantOf","#hasDependant","Owner/Author","Misc","Notes"</xsl:text>
<xsl:variable name="quote">"</xsl:variable>
<xsl:variable name="apos">'</xsl:variable>

<xsl:for-each select="child::*">
            <xsl:choose>
                <xsl:when test="name(.) = 'Rule'">
"<xsl:value-of select="@name"/>","<xsl:value-of select="description"/>","<xsl:if test="contains(replace(./def/text(),$quote,''), 'Type=Normal ID=')">Normal</xsl:if><xsl:if test="contains(replace(./def/text(),$quote,''), 'Type=Lightweight ID=')">Lightweight</xsl:if><xsl:if test="contains(replace(./def/text(),$quote,''), 'Type=Prepersist ID=')">Prepersist</xsl:if>",<xsl:if test="active='0'">"NO-A"</xsl:if><xsl:if test="active='1'">"YES"</xsl:if><xsl:if test="active='2'">"NO"</xsl:if>,"<xsl:value-of select="concat(replace(replace(replace(replace(replace(substring-before(substring-after(./def/text(),'Threshold='),'Condition ConditionType='),'&#xA;',''),'&lt;',''),'&gt;',''),$quote,''),'^\s+|\s+$', ''),' in ',replace(replace(concat(substring-before(substring-after(./def/text(),'TimeWindowSize='),' TimeUnit='),substring-before(substring-after(./def/text(),'TimeUnit='),' Threshold=')),$quote,' '),'^\s+|\s+$', ''))"/>","<xsl:value-of select="@id"/>","<xsl:value-of select="@versionID"/>","","<xsl:value-of select="count(childOf/list/ref)"/>","<xsl:value-of select="count(dependantOf/list/ref)"/>","","","<xsl:value-of select="replace(replace(./def/text(), $quote, $apos),'&#xA;','.')" disable-output-escaping="no"/>","<xsl:for-each select="hasNote/list/ref"><xsl:value-of select="@id"/><xsl:attribute name="id"><xsl:value-of select="Note/@id" /></xsl:attribute></xsl:for-each>"</xsl:when>
</xsl:choose></xsl:for-each>

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

所需的输出,应该以我的CSV输出格式显示来自Note的信息。

Name, Description, RuleType, Active, Threshold, ID, Version ID, ALias, Childof, Depandatof, hasdependant, owner/author, Misc, **Note**
Rules1, Used to manage user, Normal, Yes, 1 in 2 minutes, 1.0,-,-,-,-,Myself, Additional information , My note lalalala | RENOTE gdfgdfgdfgfd

其中Note是Note / data中的数据,在我的例子中:我的注释lalalala

我尝试使用该部分代码访问注释信息,但它不起作用

"<xsl:for-each select="hasNote/list/ref"><xsl:value-of select="@id"/><xsl:attribute name="id"><xsl:value-of select="Note/@id" /></xsl:attribute></xsl:for-each>"

XML:

       <Note id="85EVs5EsBABCAem1CaU3lEQ==" name="85EVs5EsBABCAem1CaU3lEQ==" action="insert" >
      <author>admin</author>
      <childOf>
         <list>
            <ref type="Group" uri="/All Notes/" id="01000100010001008"/>
         </list>
      </childOf>
      <createTime>1425466476004</createTime>
      <data>My note lalalala</data>
      <noteOf>
         <list>
            <ref type="Rule" uri="/All Rules/" id="5-I5qOkoBABCj2Yy+wpORuA=="/>
         </list>
      </noteOf>
   </Note>
   <Note id="8D5ds5EsBABCAfGc3-q2h+Q==" name="8D5ds5EsBABCAfGc3-q2h+Q==" action="insert" >
      <author>admin</author>
      <childOf>
         <list>
            <ref type="Group" uri="/All Notes/" id="01000100010001008"/>
         </list>
      </childOf>
      <createTime>1425466496783</createTime>
      <data>RENOTE gdfgdfgdfgfd</data>
      <noteOf>
         <list>
            <ref type="Rule" uri="/All Rules/" id="5-I5qOkoBABCj2Yy+wpORuA=="/>
         </list>
      </noteOf>
   </Note>
<Rule id="5l+jzGUoBABChieXrzh1TVQ==" name="ruleexemple" versionID="V1.0" action="insert" >
<active>1</active>
      <childOf>
         <list>
            <ref type="Group" uri="/All Rules" id="0S7GEnUEBABCGDB3i0QUfrw=="/>
         </list>
      </childOf>

<def><![CDATA[<Rule Name="ruleexemple" Type="Normal" ID="5-I5qOkoBABCj2Yy+wpORuA==">
  <Description>My Own Description</Description>
  <Query>
    <FromClause>
      <Table Name="Event" Alias="event1" AliasType="Positive" />
    </FromClause>
    <WhereClause TimeWindowSize="2" TimeUnit="Minute" Threshold="1">
      <Condition ConditionType="Positive" TableAlias="event1">
      </Condition>

</Rule>]]></def>
      <dependantOf>
         <list>
            <ref type="List" uri="/All Lists/" id="H47NgOkoBABDBEBnyq05r8g=="/>
            <ref type="List" uri="/All Lists" id="HaVFbOkoBABCjACrgyZldRw=="/>
         </list>
      </dependantOf>
      <description>My Own Description</description>
      <hasNote>
         <list>
            <ref type="Note" uri="/All Notes/85EVs5EsBABCAem1CaU3lEQ==" id="85EVs5EsBABCAem1CaU3lEQ=="/>
            <ref type="Note" uri="/All Notes/8D5ds5EsBABCAfGc3-q2h+Q==" id="8D5ds5EsBABCAfGc3-q2h+Q=="/>
         </list>
      </hasNote>
</Rule>

2 个答案:

答案 0 :(得分:0)

<xsl:for-each>中,上下文节点将移动到XPath表达式中的选定元素。

要检索所需信息,您应该使用以下内容:

<xsl:for-each select="hasNote/list/ref">
  <xsl:variable name="current.id">
    <xsl:value-of select="@id"/>
  </xsl:variable>

  <xsl:value-of select="//Note[@id = $current.id]/data" />
</xsl:for-each>

正如您提到的那样,如果您的XML非常大,那么使用<xsl:key>以更有效的方式获取<Note>可能是个好主意。

答案 1 :(得分:0)

BAse对potame的回答。

我像这样扩展了xslt

  <xsl:for-each select="hasNote/list/ref">
     <xsl:variable name="current.id">
       <xsl:value-of select="@id"/>
     </xsl:variable>
     created by: 
     <xsl:value-of select="//Note[@id = $current.id]/author" />
      on 
     <xsl:value-of select="//Note[@id = $current.id]/createTime" />
      With comment: 
     <xsl:value-of select="//Note[@id = $current.id]/data" />
      |
  </xsl:for-each>

现在我将尝试从createTime转换值,它是Unix时间戳格式,以人类可读格式转换。

我认为xsl有一些功能。不是吗?