2012-08-24 16 views
5

Trong ví dụ mã này, tôi có 2 thách thức là đặt nút B1 sau nút B và trước nút C, D và E và thách thức thứ hai là Thêm nút KEY thứ hai vào cấu trúc/ROOT/E/OTHER/DEAL/KEYS.Cách áp dụng nhiều định nghĩa mẫu trong đó mỗi định dạng trong đó thay đổi cấu trúc XML tương tự

Mẫu này XML:

 <ROOT> 
      <A>some A text</A> 
      <B>some B text</B> 
      <C>some C text</C> 
      <D>some D text</D> 
      <E> 
      <OTHER> 
       <DEAL> 
       <KEYS> 
        <KEY> 
        <KeyIdentifierType>KeyIdentifierTypeA</KeyIdentifierType> 
        <KeyValue>123456|1</KeyValue> 
        </KEY> 
       </KEYS> 
       </DEAL> 
      </OTHER> 
      </E> 
     </ROOT> 

sau khi chuyển đổi:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
     <xsl:strip-space elements="*"/> 
     <xsl:output method="xml" indent="yes"/> 

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

     <!-- Identifiers are added by the system. Need to pass parms from the calling program --> 
     <xsl:template match="ROOT" name="add-B1"> 
      <xsl:variable name="elements-after" select="C|D|E"/> 
      <xsl:copy> 
       <xsl:copy-of select="* except $elements-after"/> 
       <B1>some B1 text</B1> 
       <xsl:copy-of select="$elements-after"/> 
      </xsl:copy> 
     </xsl:template> 

     <!-- KEY is added by the system. Need to pass parms from the calling program --> 
     <xsl:template match="ROOT/E/OTHER/DEAL/KEYS" name="add-KEYS"> 
      <xsl:param name="KeyIdentifierTypeB">654321|1</xsl:param> 
      <xsl:copy> 
       <xsl:copy-of select="*"/> 
       <KEY> 
        <KeyIdentifierType>KeyIdentifierTypeB</KeyIdentifierType> 
        <KeyValue> 
         <xsl:value-of select="$KeyIdentifierTypeB"/> 
        </KeyValue> 
       </KEY> 
      </xsl:copy> 
     </xsl:template> 
    </xsl:stylesheet> 

trở thành:

 <?xml version="1.0" encoding="UTF-8"?> 
     <ROOT> 
      <A>some A text</A> 
      <B>some B text</B> 
      <B1 xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">some B1 text</B1> 
      <C>some C text</C> 
      <D>some D text</D> 
      <E> 
       <OTHER> 
        <DEAL> 
         <KEYS> 
          <KEY> 
           <KeyIdentifierType>KeyIdentifierTypeA</KeyIdentifierType> 
           <KeyValue>123456|1</KeyValue> 
          </KEY> 
         </KEYS> 
        </DEAL> 
       </OTHER> 
      </E> 
     </ROOT> 

tại sao định nghĩa mẫu thứ hai đã được bỏ qua hoàn toàn?

Trường mã đầu tiên đã được giải quyết Nút B1 được đặt sau nút B và trước nút C, D và E hoặc các nút B1 khác được đặt và các nút phải nằm sau: C, D và E
Mẫu khớp thứ hai = "ROOT/E/KHÁC/DEAL/KEYS" cần thỏa mãn phần thách thức thứ hai: Thêm nút KEY thứ hai vào cấu trúc/ROOT/E/OTHER/DEAL/KEYS, đã bị bỏ qua hoàn toàn. Ngoài thực tế này, nếu bạn nhận xét mẫu đầu tiên khớp với nút ROOT, mẫu khớp thứ hai = "ROOT/E/OTHER/DEAL/KEYS" sẽ hoạt động chính xác, nó sẽ thêm khóa bổ sung, nhưng tôi không không biết tại sao mẫu khớp đầu tiên luôn ghi đè thứ hai. Tôi thử xsl: template match = "ROOT/E/KHÁC/DEAL/KEYS ... và xsl: for-each select = ... và xsl: call-template name =" add-KEYS "nhưng không có gì giúp tôi Tôi thực sự hiểu rằng, các mẫu áp dụng, khớp các mẫu nút có cấu trúc cao hơn với mức độ ưu tiên cao nhất. Thay đổi vị trí của mẫu trong tệp XSLT sẽ không có bất kỳ tác động nào, nó sẽ không đọc nó trong chuỗi dòng chính xác, thay vào đó "áp dụng mẫu" cho mỗi mẫu phù hợp sẽ thực hiện một thay đổi về cấu trúc XML, ngầm nó sẽ làm cho "cho mỗi" cho chúng tôi, nhưng tôi không làm thế nào để "tư vấn" mẫu thứ hai mà cấu trúc đã được thay đổi và tại sao tôi nên làm điều đó, bởi vì đối sánh mẫu thứ hai đang tìm kiếm một vị trí XPath khác, btw chưa bao giờ được chạm vào từ mẫu đầu tiên. g trong trường hợp của tôi? ... và thực hành tốt nhất là làm thế nào để làm điều đó?

Kết quả mong đợi:

 <?xml version="1.0" encoding="UTF-8"?> 
     <ROOT> 
      <A>some A text</A> 
      <B>some B text</B> 
      <B1>some B1 text</B1> 
      <C>some C text</C> 
      <D>some D text</D> 
      <E> 
       <OTHER> 
        <DEAL> 
         <KEYS> 
          <KEY> 
           <KeyIdentifierType>KeyIdentifierTypeA</KeyIdentifierType> 
           <KeyValue>123456|1</KeyValue> 
          </KEY> 
          <KEY> 
           <KeyIdentifierType>KeyIdentifierTypeB</KeyIdentifierType> 
           <KeyValue>654321|1</KeyValue> 
          </KEY> 
         </KEYS> 
        </DEAL> 
       </OTHER> 
      </E> 
     </ROOT> 

Trả lời

3

Mẫu thứ hai match="ROOT/E/OTHER/DEAL/KEYS" rằng nên đáp ứng các phần thử thách thứ hai: Thêm nút KEY thứ hai để cấu trúc /ROOT/E/OTHER/DEAL/KEYS, đã bị bỏ qua hoàn toàn.

Vấn đề là trong mẫu khớp với ROOT không có bất kỳ xsl:apply-templates nào. Mẫu chỉ được chọn để thực thi theo kết quả của lệnh xsl:apply-templates. Trong mã của bạn không có bất kỳ xsl:apply-templates, do đó bộ xử lý XSLT không áp dụng các mẫu nữa và hoàn thành việc thực thi.

Sẽ khác nếu bạn thay thế xsl:copy-of bằng xsl:apply-templates.

Sau đây là cách để làm điều này:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

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

<xsl:template match="/*"> 
    <xsl:copy> 
    <xsl:apply-templates select="@*|B/preceding-sibling::node()"/> 
    <xsl:apply-templates select="B"/> 
    <B1>some B1 text</B1> 
    <xsl:apply-templates select="B/following-sibling::node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="KEY"> 
    <xsl:copy> 
    <xsl:apply-templates select="@*|node()"/> 
    <KEY> 
    <KeyIdentifierType>KeyIdentifierTypeB</KeyIdentifierType> 
    <KeyValue> 
    <xsl:value-of select="'654321|1'"/> 
    </KeyValue> 
    </KEY> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

Khi chuyển đổi này được áp dụng trên các tài liệu XML cung cấp:

<ROOT> 
    <A>some A text</A> 
    <B>some B text</B> 
    <C>some C text</C> 
    <D>some D text</D> 
    <E> 
     <OTHER> 
      <DEAL> 
       <KEYS> 
        <KEY> 
         <KeyIdentifierType>KeyIdentifierTypeA</KeyIdentifierType> 
         <KeyValue>123456|1</KeyValue> 
        </KEY> 
       </KEYS> 
      </DEAL> 
     </OTHER> 
    </E> 
</ROOT> 

các truy nã, kết quả chính xác được sản xuất:

<ROOT> 
    <A>some A text</A> 
    <B>some B text</B> 
    <B1>some B1 text</B1> 
    <C>some C text</C> 
    <D>some D text</D> 
    <E> 
     <OTHER> 
     <DEAL> 
      <KEYS> 
       <KEY> 
        <KeyIdentifierType>KeyIdentifierTypeA</KeyIdentifierType> 
        <KeyValue>123456|1</KeyValue> 
        <KEY> 
        <KeyIdentifierType>KeyIdentifierTypeB</KeyIdentifierType> 
        <KeyValue>654321|1</KeyValue> 
        </KEY> 
       </KEY> 
      </KEYS> 
     </DEAL> 
     </OTHER> 
    </E> 
</ROOT> 
+0

Cảm ơn bạn rất nhiều! –

+0

@ user1619586, Bạn được chào đón. –