2013-04-10 221 views
0

我需要查询一个大的XML文件,以提取仅包含具有等于给定参数的属性的所需节点的子XML树。XSLT按属性查询节点

这里是我的源文件

  <a:level1 xmlns:a="some:a" xmlns:b="some:b" 
         xmlns:c="some:c" xmlns:d="some:d"> 
       <a:level2> 
        <b:level3> 
         <b:date a:value="TODAY"> 
          <c:level4> 
           <d:level5> 
            <d:level6 a:value="AAA"> 
             <d:level7 a:value="AAA_AAA"> 
              <d:level8 a:value="XXX/123"> 
               <d:leaf a:value="150415"> 
                <b:leaf1>100</b:leaf1> 
                <b:leaf2>100</b:leaf2> 
               </d:leaf> 
               <d:leaf a:value="200814"> 
                <b:leaf1>1961</b:leaf1> 
                <b:leaf2>1961</b:leaf2> 
               </d:leaf> 
              </d:level8> 
             </d:level7> 
            </d:level6> 
            <d:level6 a:value="BBB"> 
             <d:level7 a:value="BBB_BBB"> 
              <d:level8 a:value="XXX/123"> 
               <d:leaf a:value="1505"> 
                <b:leaf1>0.42</b:leaf1> 
                <b:leaf2>0.42</b:leaf2> 
               </d:leaf> 
              </d:level8> 
             </d:level7> 
            </d:level6> 
           </d:level5> 
          </c:level4> 
         </b:date> 
        </b:level3> 
       </a:level2> 
      </a:level1> 

,这里是我的样式表:

 <?xml version="1.0" encoding="UTF-8"?> 
     <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
      xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      xmlns:a="xmlCache"> 
      <xsl:param name="myparam" as="xs:string" required="no"/> 
      <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/> 
      <xsl:strip-space elements="*"/> 

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

      <xsl:template match="@*"> 
       <xsl:message><xsl:value-of select="@a:value"/></xsl:message> 
       <xsl:if test="@a:value=$myparam"> 
        <xsl:call-template name="identity"/> 
       </xsl:if> 
      </xsl:template> 
     </xsl:stylesheet> 

但它似乎不工作。有人可以帮忙吗?

更新:对不清楚的问题抱歉。我想提取整个子集的XML树。例如,如果参数为AAA,则输出为:

  <a:level1 xmlns:a="some:a" xmlns:b="some:b" 
         xmlns:c="some:c" xmlns:d="some:d"> 
       <a:level2> 
        <b:level3> 
         <b:date a:value="TODAY"> 
          <c:level4> 
           <d:level5> 
            <d:level6 a:value="AAA"> 
             <d:level7 a:value="AAA_AAA"> 
              <d:level8 a:value="XXX/123"> 
               <d:leaf a:value="150415"> 
                <b:leaf1>100</b:leaf1> 
                <b:leaf2>100</b:leaf2> 
               </d:leaf> 
               <d:leaf a:value="200814"> 
                <b:leaf1>1961</b:leaf1> 
                <b:leaf2>1961</b:leaf2> 
               </d:leaf> 
              </d:level8> 
             </d:level7> 
            </d:level6> 
           </d:level5> 
          </c:level4> 
         </b:date> 
        </b:level3> 
       </a:level2> 
      </a:level1> 
+0

当你说这是“不工作”,它是如何失败? 正如所写,它似乎复制了所有元素和属性的一个子集。 但是你想要什么输出,例如当$ myparam =“TODAY”时?您尚未明确说明要求。 – 2013-04-10 10:56:24

+0

对不起,我更新了我的问题。谢谢。 – gasparino 2013-04-16 06:01:10

回答

0

更多通过猜测类似以下内容的是您正在寻找的内容。

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:a="xmlCache"> 
    <xsl:param name="myparam"/> 
    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

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

<xsl:template match ="node()|@*"> 
    <xsl:choose> 
     <xsl:when test="@*[name()='a:value']=$myparam"> 
      <xsl:copy> 
       <xsl:apply-templates select="@*|*" mode="copy"/> 
      </xsl:copy> 
     </xsl:when> 
     <xsl:when test="descendant::*/@*[name()='a:value']=$myparam"> 
      <xsl:copy> 
       <xsl:apply-templates select="@*" mode="copy"/> 
       <xsl:apply-templates select="*" /> 
      </xsl:copy> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:apply-templates /> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

</xsl:stylesheet> 

E.g称为蒙山xsltproc的和param myparam

xsltproc --stringparam myparam BBB in.xsl in.xml 

它产生如(有希望)预期的输出。

<a:level1 xmlns:a="some:a" xmlns:b="some:b" xmlns:c="some:c" xmlns:d="some:d"> 
    <a:level2> 
    <b:level3> 
     <b:date a:value="TODAY"> 
     <c:level4> 
      <d:level5> 
      <d:level6 a:value="BBB"> 
       <d:level7 a:value="BBB_BBB"> 
       <d:level8 a:value="XXX/123"> 
        <d:leaf a:value="1505"> 
        <b:leaf1>0.42</b:leaf1> 
        <b:leaf2>0.42</b:leaf2> 
        </d:leaf> 
       </d:level8> 
       </d:level7> 
      </d:level6> 
      </d:level5> 
     </c:level4> 
     </b:date> 
    </b:level3> 
    </a:level2> 
</a:level1> 
+0

感谢您的帮助。但是,我只是更新我的问题。我想从根节点向匹配的节点提取整个XML子树。 – gasparino 2013-04-16 05:24:08

+0

@ gasparino我将自己的答案改编为适应要求。 – 2013-04-16 08:22:53

+0

它完美地工作。非常感谢。 – gasparino 2013-04-16 08:41:19