2012-05-03 54 views
13

Tôi đang cố gắng viết một XSL sẽ xuất ra một tập con nhất định của các trường từ XML nguồn. Tập hợp con này sẽ được xác định tại thời gian chuyển đổi, bằng cách sử dụng một tài liệu cấu hình XML bên ngoài có chứa các tên trường và các thông tin cụ thể khác (chẳng hạn như độ dài đệm).Lồng nhau cho mỗi vòng lặp, truy cập phần tử bên ngoài với biến từ vòng lặp bên trong

Vì vậy, đây là hai for-each vòng:

  • Một lặp bên ngoài qua các hồ sơ để truy cập kỷ lục lĩnh vực của họ bằng cách kỷ lục.
  • Phần bên trong lặp lại qua tài liệu XML cấu hình để lấy các trường được cấu hình từ bản ghi hiện tại.

Tôi đã xem trong In XSLT how do I access elements from the outer loop from within nested loops? rằng phần tử hiện tại trong vòng ngoài có thể được lưu trữ trong một xsl:variable. Nhưng sau đó tôi phải xác định một biến mới bên trong vòng lặp bên trong để lấy tên trường. Sản lượng nào cho câu hỏi: Có thể truy cập một đường dẫn trong đó có hai biến không?

Ví dụ, các nguồn tài liệu XML trông giống như:

<data> 
    <dataset> 
     <record> 
      <field1>value1</field1> 
      ... 
      <fieldN>valueN</fieldN> 
     </record> 
    </dataset> 
    <dataset> 
     <record> 
      <field1>value1</field1> 
      ... 
      <fieldN>valueN</fieldN> 
     </record> 
    </dataset> 
</data> 

Tôi muốn có một file XML bên ngoài trông như:

<configuration> 
    <outputField order="1"> 
     <fieldName>field1</fieldName> 
     <fieldPadding>25</fieldPadding> 
    </outputField> 
    ... 
    <outputField order="N"> 
     <fieldName>fieldN</fieldName> 
     <fieldPadding>10</fieldPadding> 
    </outputField> 
</configuration> 

Các XSL Tôi đã có cho đến nay:

<xsl:variable name="config" select="document('./configuration.xml')"/> 
<xsl:for-each select="data/dataset/record"> 
    <!-- Store the current record in a variable --> 
    <xsl:variable name="rec" select="."/> 
    <xsl:for-each select="$config/configuration/outputField"> 
     <xsl:variable name="field" select="fieldName"/> 
     <xsl:variable name="padding" select="fieldPadding"/> 

     <!-- Here's trouble --> 
     <xsl:variable name="value" select="$rec/$field"/> 

     <xsl:call-template name="append-pad"> 
      <xsl:with-param name="padChar" select="$padChar"/> 
      <xsl:with-param name="padVar" select="$value"/> 
      <xsl:with-param name="length" select="$padding"/> 
     </xsl:call-template> 

    </xsl:for-each> 
    <xsl:value-of select="$newline"/> 
</xsl:for-each> 

Tôi khá mới đối với XSL, vì vậy đây có thể là câu hỏi vô lý và cách tiếp cận cũng có thể đơn giản ng (tức là lặp lại vòng lặp bên trong cho một nhiệm vụ có thể được thực hiện một lần khi bắt đầu). Tôi đánh giá cao bất kỳ lời khuyên nào về cách chọn giá trị trường từ phần tử vòng lặp bên ngoài và, tất nhiên, mở ra những cách tốt hơn để tiếp cận nhiệm vụ này.

Trả lời

13

Biểu định kiểu của bạn trông gần như tốt. Chỉ cần biểu thức $rec/$field không có ý nghĩa bởi vì bạn không thể kết hợp hai bộ/chuỗi nút theo cách này. Thay vào đó, bạn nên so sánh tên của các phần tử bằng cách sử dụng hàm name(). Nếu tôi hiểu vấn đề của bạn một cách chính xác, một cái gì đó như thế này nên làm việc:

<xsl:variable name="config" select="document('./configuration.xml')"/> 
<xsl:for-each select="data/dataset/record"> 
    <xsl:variable name="rec" select="."/> 
    <xsl:for-each select="$config/configuration/outputField"> 
     <xsl:variable name="field" select="fieldName"/> 
     ... 
     <xsl:variable name="value" select="$rec/*[name(.)=$field]"/> 
     ...  
    </xsl:for-each> 
    <xsl:value-of select="$newline"/> 
</xsl:for-each> 

Biến lĩnh vực là không cần thiết trong ví dụ này. Bạn cũng có thể sử dụng hàm current() để truy cập nút ngữ cảnh hiện tại của vòng lặp bên trong:

<xsl:variable name="value" select="$rec/*[name(.)=current()/fieldName]"/> 
Các vấn đề liên quan