XSLT选择通过动态父节点的子节点

时间:2014-03-06 17:38:56

标签: xml xslt xsd

我正在尝试将此分层Web服务结果集转换为表格格式。我想抓住以下内容:

  • START_TIME

  • END_TIME

  • 的web_url

  • scheduled_report_id

问题在于<versions>下的节点<_1794050>是动态的,并且随着每个<results>而变化,所以在我的XSD中,我将其作为any。我愿意对我的架构定义进行更改或者如何通过XSLT访问它,但此时我无法更改输入格式。

输入XML

<?xml version="1.0" encoding="UTF-8"?><wrap>
  <total>4259</total>
  <query>
    <start>91</start>
    <end>100</end>
  </query>
  <results>
    <public_id>jx6t3sfnelq2bpzpvmeg8i74zv7gc5</public_id>
    <name>Facebook Post Insights Report</name>
    <start_time>2014-02-23T01:00:00-05:00</start_time>
    <end_time>2014-03-02T00:59:59-05:00</end_time>
    <created_at>2014-03-04T03:03:52-05:00</created_at>
    <versions>
      <_1794050>
        <web_url>https://URLHERE.com</web_url>
        <excel_url>https://URLHERE.com</excel_url>
        <data_url>https://URLHERE.com</data_url>
      </_1794050>
    </versions>
    <scheduled_report_id>6303</scheduled_report_id>
  </results>
</wrap>

XSD架构

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified">
  <xs:element name="wrap">
    <xs:complexType>
      <xs:sequence>
        <xs:element type="xs:short" name="total"/>
        <xs:element name="query">
          <xs:complexType>
            <xs:sequence>
              <xs:element type="xs:byte" name="start"/>
              <xs:element type="xs:byte" name="end"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="results" maxOccurs="unbounded" minOccurs="0">
          <xs:complexType>
            <xs:sequence>
              <xs:element type="xs:string" name="public_id"/>
              <xs:element type="xs:string" name="name"/>
              <xs:element type="xs:dateTime" name="start_time"/>
              <xs:element type="xs:dateTime" name="end_time"/>
              <xs:element type="xs:dateTime" name="created_at"/>
              <xs:element name="versions">
                <xs:complexType>
                  <xs:sequence>
                    <xs:any/>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
              <xs:element type="xs:string" name="scheduled_report_id"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

XSLT到目前为止......

<xslt:stylesheet xmlns:xslt="http://www.w3.org/1999/XSL/Transform" xmlns:csw-xform="http://www.compositesw.com/2003/xform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">
  <xslt:template match="/">
    <xslt:variable name="_public_id"/>
    <xslt:variable name="_start_time"/>
    <xslt:variable name="_end_time"/>
    <xslt:variable name="_created_at"/>
    <xslt:variable name="_scheduled_report_id"/>
    <xslt:element name="results">
      <xslt:for-each select="wrap">
        <xslt:for-each select="results">
          <xslt:variable name="_public_id" select="public_id"/>
          <xslt:variable name="_start_time" select="start_time"/>
          <xslt:variable name="_end_time" select="end_time"/>
          <xslt:variable name="_created_at" select="created_at"/>
          <xslt:variable name="_scheduled_report_id" select="scheduled_report_id"/>
          <xslt:element name="result">
            <xslt:element name="public_id">
              <xslt:value-of select="$_public_id"/>
            </xslt:element>
            <xslt:element name="start_time">
              <xslt:value-of select="$_start_time"/>
            </xslt:element>
            <xslt:element name="end_time">
              <xslt:value-of select="$_end_time"/>
            </xslt:element>
            <xslt:element name="created_at">
              <xslt:value-of select="$_created_at"/>
            </xslt:element>
            <xslt:element name="scheduled_report_id">
              <xslt:value-of select="$_scheduled_report_id"/>
            </xslt:element>
          </xslt:element>
        </xslt:for-each>
      </xslt:for-each>
    </xslt:element>
  </xslt:template>
</xslt:stylesheet>

1 个答案:

答案 0 :(得分:1)

使用versions/*/web_url例如

<xsl:template match="results">
  <xsl:value-of select="versions/*/web_url"/>
</xsl:template>

您可以读出web_url元素中versions元素的任何子节点的results子节点作为上下文节点。或者,您可以使用versions//web_url访问任何web_url后代。

正如您现在添加了一些XSLT,在<xslt:for-each select="results">内部,您可以使用<xslt:variable name="web_url" select="versions/*/web_url"/>,然后以与使用其他变量相同的方式输出它,或者像我一样,只需使用文字结果元素<web_url><xslt:value-of select="$web_url"/></web_url>。当然,您甚至不需要变量,但可以使用<web_url><xslt:value-of select="versions/*/web_url"/></web_url>