【问题标题】:XSLT query - finding value based on attribute from previous nodeXSLT 查询 - 根据前一个节点的属性查找值
【发布时间】:2012-10-30 20:39:24
【问题描述】:

我必须查询一个属性值,然后我必须从另一个节点中找到另一个属性值。

这是我的 XML 的样子:

    <?xml version="1.0" encoding="UTF-8"?>
    <order main="0" state="ntype" otdType="SeeBeyond/eGate/OTDLead/UD1_0" identifier="Test/_453220556">
     <enum id="2" name="order" size="3">
      <item name="seq" value="0"/>
      <item name="any" value="1"/>
      <item name="mix" value="2"/>
     </enum>
     <enum id="3" name="align" size="8">
      <item name="blind" value="0"/>
      <item name="begin" value="1"/>
      <item name="exact" value="2"/>
      <item name="final" value="3"/>
      <item name="inter" value="4"/>
      <item name="oneof" value="5"/>
      <item name="regex" value="6"/>
      <item name="super" value="7"/>
     </enum>
     <enum id="4" name="delimTerm" size="4">
      <item name="never" value="0"/>
      <item name="allow" value="1"/>
      <item name="cheer" value="2"/>
      <item name="force" value="3"/>
     </enum>
     <enum id="5" name="delimKind" size="3">
      <item name="escape" value="0"/>
      <item name="normal" value="1"/>
      <item name="repeat" value="2"/>
     </enum>
     <enum id="6" name="nodeType" size="6">
      <item name="alter" value="0"/>
      <item name="array" value="1"/>
      <item name="delim" value="2"/>
      <item name="fixed" value="3"/>
      <item name="group" value="4"/>
      <item name="trans" value="5"/>
     </enum>
     <overlay type="structure">
      <class id="34" name="com.stc.otd.runtime.OtdOutputStream" java="com.stc.otd.runtime.OtdOutputStream" type="baseclass"/>
      <class id="4" name="java.lang.String" java="java.lang.String" type="baseclass"/>
      <class id="39" name="com.stc.otd.runtime.OtdInputStream" java="com.stc.otd.runtime.OtdInputStream" type="baseclass"/>
      <class id="43" name="byte" java="byte" type="primitive"/>
      <class id="44" name="array of byte" java="byte[]" type="arraytype" base="43"/>
      <class id="25" java="ud1.Test_453220556.Env1.Test" type="nodeclass"/>
      <class id="27" java="ud1.Test_453220556.Test" type="nodeclass">
       <method id="55" name="unmarshalFromString" java="unmarshalFromString" result="31">
        <param id="56" name="in" java="in" type="28"/>
        <throw id="57" name="java.io.IOException" java="java.io.IOException"/>
        <throw id="58" name="com.stc.otd.runtime.UnmarshalException" java="com.stc.otd.runtime.UnmarshalException"/>
       </method>
       <method id="32" name="reset" java="reset" result="31"/>
       <method id="59" name="setDecoding" java="setDecoding" result="31">
        <param id="60" name="code" java="code" type="28"/>
       </method>
       <method id="45" name="marshalToBytes" java="marshalToBytes" result="44">
        <throw id="46" name="java.io.IOException" java="java.io.IOException"/>
        <throw id="47" name="com.stc.otd.runtime.MarshalException" java="com.stc.otd.runtime.MarshalException"/>
       </method>
       <method id="30" name="check" java="check" result="29"/>
       <method id="65" name="setPostCoding" java="setPostCoding" result="31">
        <param id="66" name="code" java="code" type="28"/>
       </method>
       <method id="38" name="unmarshal" java="unmarshal" result="31">
        <param id="40" name="in" java="in" type="39"/>
        <throw id="42" name="com.stc.otd.runtime.UnmarshalException" java="com.stc.otd.runtime.UnmarshalException"/>
        <throw id="41" name="java.io.IOException" java="java.io.IOException"/>
       </method>
       <method id="63" name="setAnteCoding" java="setAnteCoding" result="31">
        <param id="64" name="code" java="code" type="28"/>
       </method>
       <method id="61" name="setEncoding" java="setEncoding" result="31">
        <param id="62" name="code" java="code" type="28"/>
       </method>
       <method id="48" name="unmarshalFromBytes" java="unmarshalFromBytes" result="31">
        <param id="49" name="in" java="in" type="44"/>
        <throw id="51" name="com.stc.otd.runtime.UnmarshalException" java="com.stc.otd.runtime.UnmarshalException"/>
        <throw id="50" name="java.io.IOException" java="java.io.IOException"/>
       </method>
       <method id="33" name="marshal" java="marshal" result="31">
        <param id="35" name="out" java="out" type="34"/>
        <throw id="37" name="com.stc.otd.runtime.MarshalException" java="com.stc.otd.runtime.MarshalException"/>
        <throw id="36" name="java.io.IOException" java="java.io.IOException"/>
       </method>
       <method id="52" name="marshalToString" java="marshalToString" result="28">
        <throw id="53" name="java.io.IOException" java="java.io.IOException"/>
        <throw id="54" name="com.stc.otd.runtime.MarshalException" java="com.stc.otd.runtime.MarshalException"/>
       </method>
      </class>
      <class id="26" java="ud1.Test_453220556.Env1.Element" type="nodeclass"/>
      <class id="29" name="array of java.lang.String" java="java.lang.String[]" type="arraytype" base="28"/>
      <class id="28" name="string" java="java.lang.String" type="baseclass"/>
      <class id="31" name="void" java="void" type="primitive"/>
      <node id="0" type="choice">
       <ref node="1" name="Test" javaName="Test" access="modify"/>
      </node>
      <node id="1" type="group" javaType="25" rootType="27">
       <prop name="public" type="boolean" value="false"/>
       <prop name="top" type="boolean" value="true"/>
       <ref node="2" name="Element" javaName="Element" access="modify"/>
      </node>
      <node id="2" type="group" javaType="26">
       <ref node="3" name="X" javaName="X" access="modify"/>
      </node>
      <node id="3" type="simple" javaType="4"/>
     </overlay>
     <overlay type="document"/>
     <overlay type="origin">
      <node id="0">
       <prop name="mainPackage" value="ud1.Test_453220556."/>
       <prop name="classNameBase" value="Test"/>
      </node>
      <node id="1">
       <prop name="rootClassName" value="ud1.Test_453220556.TestMainImpl.Root1"/>
       <prop name="order" type="2" value="seq"/>
       <prop name="nodeType" type="enum:array,delim,fixed,group,trans" value="group"/>
      </node>
      <node id="2">
       <prop name="order" type="2" value="seq"/>
       <prop name="length" type="integer" value="10"/>
       <prop name="nodeType" type="enum:array,delim,fixed,group,trans" value="fixed"/>
      </node>
      <node id="3">
       <prop name="align" type="3" value="blind"/>
       <prop name="length" type="integer" value="10"/>
       <prop name="nodeType" type="enum:array,delim,fixed,trans" value="fixed"/>
      </node>
     </overlay>
    </order>

示例:我需要查询的属性值在第 101 行。我必须获取引用节点的节点 ID,在本示例中为“3”:

  <node id="2" type="group" javaType="26">
     <ref node="3" name="X" javaName="X" access="modify"/>
  </node>

然后我需要在 XML 中进一步搜索,它应该找到 id="3" 的节点,然后查找名为“length”的属性并返回它的值,在此示例中为“10”:

  <node id="3">
    <prop name="align" type="3" value="blind"/>
    <prop name="length" type="integer" value="10"/>
    <prop name="nodeType" type="enum:array,delim,fixed,trans" value="fixed"/>
  </node>

我已经编写了以下 XSLT 代码,但需要添加更多代码才能正确获取长度部分:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
      <html>
      <body>
        <h2>My OTD type</h2>
        <table border="1">
          <tr bgcolor="#9acd32">
            <th>Name</th>
            <th>Column Length</th>
          </tr>
          <xsl:for-each select="/order/overlay/node/ref">
          <tr>
            <td><xsl:value-of select="@name" /></td>

    <xsl:for-each select="/order/overlay[3]/node">
            <td><xsl:value-of select="props/@value" /></td>
    </xsl:for-each>

          </tr>
          </xsl:for-each>
        </table>
      </body>
      </html>
    </xsl:template>
    </xsl:stylesheet>

请建议如何获得所需的结果。

【问题讨论】:

    标签: xml xslt xquery


    【解决方案1】:

    此转换使用键来实现最大效率,并展示了如何获得所需的值:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output method="text"/>
    
     <xsl:key name="kNodeByTypeAndId" match="overlay/node"
      use="concat(../@type,'+',@id)"/>
    
     <xsl:template match="/">
         <xsl:value-of select=
          "key('kNodeByTypeAndId',
               concat('origin+',key('kNodeByTypeAndId', 'structure+2')/ref/@node)
               )
               /prop[@name='length']/@value
         "/>
     </xsl:template>
    </xsl:stylesheet>
    

    当此转换应用于提供的 XML 文档时:

    <order main="0" state="ntype" otdType="SeeBeyond/eGate/OTDLead/UD1_0"
    identifier="Test/_453220556">
        <enum id="2" name="order" size="3">
            <item name="seq" value="0"/>
            <item name="any" value="1"/>
            <item name="mix" value="2"/>
        </enum>
        <enum id="3" name="align" size="8">
            <item name="blind" value="0"/>
            <item name="begin" value="1"/>
            <item name="exact" value="2"/>
            <item name="final" value="3"/>
            <item name="inter" value="4"/>
            <item name="oneof" value="5"/>
            <item name="regex" value="6"/>
            <item name="super" value="7"/>
        </enum>
        <enum id="4" name="delimTerm" size="4">
            <item name="never" value="0"/>
            <item name="allow" value="1"/>
            <item name="cheer" value="2"/>
            <item name="force" value="3"/>
        </enum>
        <enum id="5" name="delimKind" size="3">
            <item name="escape" value="0"/>
            <item name="normal" value="1"/>
            <item name="repeat" value="2"/>
        </enum>
        <enum id="6" name="nodeType" size="6">
            <item name="alter" value="0"/>
            <item name="array" value="1"/>
            <item name="delim" value="2"/>
            <item name="fixed" value="3"/>
            <item name="group" value="4"/>
            <item name="trans" value="5"/>
        </enum>
        <overlay type="structure">
            <class id="34" name="com.stc.otd.runtime.OtdOutputStream" java="com.stc.otd.runtime.OtdOutputStream" type="baseclass"/>
            <class id="4" name="java.lang.String" java="java.lang.String" type="baseclass"/>
            <class id="39" name="com.stc.otd.runtime.OtdInputStream" java="com.stc.otd.runtime.OtdInputStream" type="baseclass"/>
            <class id="43" name="byte" java="byte" type="primitive"/>
            <class id="44" name="array of byte" java="byte[]" type="arraytype" base="43"/>
            <class id="25" java="ud1.Test_453220556.Env1.Test" type="nodeclass"/>
            <class id="27" java="ud1.Test_453220556.Test" type="nodeclass">
                <method id="55" name="unmarshalFromString" java="unmarshalFromString" result="31">
                    <param id="56" name="in" java="in" type="28"/>
                    <throw id="57" name="java.io.IOException" java="java.io.IOException"/>
                    <throw id="58" name="com.stc.otd.runtime.UnmarshalException" java="com.stc.otd.runtime.UnmarshalException"/>
                </method>
                <method id="32" name="reset" java="reset" result="31"/>
                <method id="59" name="setDecoding" java="setDecoding" result="31">
                    <param id="60" name="code" java="code" type="28"/>
                </method>
                <method id="45" name="marshalToBytes" java="marshalToBytes" result="44">
                    <throw id="46" name="java.io.IOException" java="java.io.IOException"/>
                    <throw id="47" name="com.stc.otd.runtime.MarshalException" java="com.stc.otd.runtime.MarshalException"/>
                </method>
                <method id="30" name="check" java="check" result="29"/>
                <method id="65" name="setPostCoding" java="setPostCoding" result="31">
                    <param id="66" name="code" java="code" type="28"/>
                </method>
                <method id="38" name="unmarshal" java="unmarshal" result="31">
                    <param id="40" name="in" java="in" type="39"/>
                    <throw id="42" name="com.stc.otd.runtime.UnmarshalException" java="com.stc.otd.runtime.UnmarshalException"/>
                    <throw id="41" name="java.io.IOException" java="java.io.IOException"/>
                </method>
                <method id="63" name="setAnteCoding" java="setAnteCoding" result="31">
                    <param id="64" name="code" java="code" type="28"/>
                </method>
                <method id="61" name="setEncoding" java="setEncoding" result="31">
                    <param id="62" name="code" java="code" type="28"/>
                </method>
                <method id="48" name="unmarshalFromBytes" java="unmarshalFromBytes" result="31">
                    <param id="49" name="in" java="in" type="44"/>
                    <throw id="51" name="com.stc.otd.runtime.UnmarshalException" java="com.stc.otd.runtime.UnmarshalException"/>
                    <throw id="50" name="java.io.IOException" java="java.io.IOException"/>
                </method>
                <method id="33" name="marshal" java="marshal" result="31">
                    <param id="35" name="out" java="out" type="34"/>
                    <throw id="37" name="com.stc.otd.runtime.MarshalException" java="com.stc.otd.runtime.MarshalException"/>
                    <throw id="36" name="java.io.IOException" java="java.io.IOException"/>
                </method>
                <method id="52" name="marshalToString" java="marshalToString" result="28">
                    <throw id="53" name="java.io.IOException" java="java.io.IOException"/>
                    <throw id="54" name="com.stc.otd.runtime.MarshalException" java="com.stc.otd.runtime.MarshalException"/>
                </method>
            </class>
            <class id="26" java="ud1.Test_453220556.Env1.Element" type="nodeclass"/>
            <class id="29" name="array of java.lang.String" java="java.lang.String[]" type="arraytype" base="28"/>
            <class id="28" name="string" java="java.lang.String" type="baseclass"/>
            <class id="31" name="void" java="void" type="primitive"/>
            <node id="0" type="choice">
                <ref node="1" name="Test" javaName="Test" access="modify"/>
            </node>
            <node id="1" type="group" javaType="25" rootType="27">
                <prop name="public" type="boolean" value="false"/>
                <prop name="top" type="boolean" value="true"/>
                <ref node="2" name="Element" javaName="Element" access="modify"/>
            </node>
            <node id="2" type="group" javaType="26">
                <ref node="3" name="X" javaName="X" access="modify"/>
            </node>
            <node id="3" type="simple" javaType="4"/>
        </overlay>
        <overlay type="document"/>
        <overlay type="origin">
            <node id="0">
                <prop name="mainPackage" value="ud1.Test_453220556."/>
                <prop name="classNameBase" value="Test"/>
            </node>
            <node id="1">
                <prop name="rootClassName" value="ud1.Test_453220556.TestMainImpl.Root1"/>
                <prop name="order" type="2" value="seq"/>
                <prop name="nodeType" type="enum:array,delim,fixed,group,trans" value="group"/>
            </node>
            <node id="2">
                <prop name="order" type="2" value="seq"/>
                <prop name="length" type="integer" value="10"/>
                <prop name="nodeType" type="enum:array,delim,fixed,group,trans" value="fixed"/>
            </node>
            <node id="3">
                <prop name="align" type="3" value="blind"/>
                <prop name="length" type="integer" value="10"/>
                <prop name="nodeType" type="enum:array,delim,fixed,trans" value="fixed"/>
            </node>
        </overlay>
    </order>
    

    产生了想要的正确结果:

    10
    

    【讨论】:

      【解决方案2】:

      这个 Xpath 应该可以工作: prop/[@type="3"]/following-sibling

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-02-13
        • 1970-01-01
        • 1970-01-01
        • 2016-10-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多