2012-10-02 38 views
5

Tôi đang trong quá trình chuyển đổi tài liệu Word thành XML. Tôi đã gặp sự cố sau:Nội dung hỗn hợp và thao tác chuỗi xóa sạch

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <p> 
     <element>This one is taken care of.</element> Some more text. „<hi rend="italics">Is this a 
      quote</hi>?” (Source). </p> 

    <p> 
     <element>This one is taken care of.</element> Some more text. „<hi rend="italics">This is a 
      quote</hi>” (Source). </p> 

    <p> 
     <element>This one is taken care of.</element> Some more text. „<hi rend="italics">This is 
      definitely a quote</hi>!” (Source). </p> 

    <p> 
     <element>This one is taken care of.</element> Some more text.„<hi rend="italics">This is a 
      first quote</hi>” (Source). „<hi rend="italics">Sometimes there is a second quote as 
      well</hi>!?” (Source). </p> 

</root> 

<p> các nút có nội dung hỗn hợp. <element> Tôi đã quan tâm đến việc lặp lại trước đó. Nhưng bây giờ vấn đề là với dấu ngoặc kép và các nguồn xuất hiện một phần trong phạm vi <hi rend= "italics"/> và một phần là các nút văn bản.

Làm thế nào tôi có thể sử dụng XSLT 2.0 để:

  1. trận đấu tất cả <hi rend="italics"> nút được ngay lập tức trước bởi các nút văn bản có ký tự cuối cùng là "“"?
  2. xuất nội dung của <hi rend="italics"><quote>...</quote>, loại bỏ dấu ngoặc kép ("„ "và" ""), nhưng bao gồm trong bất kỳ câu hỏi và dấu chấm than nào xuất hiện ngay sau anh chị em của <hi rend="italics">?
  3. chuyển đổi nút văn bản giữa "(" và ")" sau nút <hi rend="italics"><source>...</source> không có dấu ngoặc.
  4. bao gồm toàn bộ điểm dừng cuối cùng.

Nói cách khác, đầu ra của tôi sẽ giống như thế này:

<root> 
<p> 
<element>This one is taken care of.</element> Some more text. <quote>Is this a quote?</quote> <source>Source</source>. 
</p> 

<p> 
<element>This one is taken care of.</element> Some more text. <quote>This is a quote</hi> <source>Source</source>. 
</p> 

<p> 
<element>This one is taken care of.</element> Some more text. <quote>This is definitely a quote!</hi> <source>Source</source>. 
</p> 

<p> 
<element>This one is taken care of.</element> Some more text. <quote>This is a first quote</quote> <source>Source</source>. <quote>Sometimes there is a second quote as well!?</quote> <source>Source</source>. 
</p> 

</root> 

Tôi chưa bao giờ bị xử lý nội dung và chuỗi thao tác hỗn hợp như thế này và toàn bộ điều thực sự là ném tôi ra. Tôi sẽ vô cùng biết ơn những lời khuyên của bạn.

+0

Dấu hỏi và dấu chấm than trong tài liệu đầu vào của bạn nằm ngoài phần tử 'hi', nhưng ở đầu ra dự kiến, chúng nằm trong phần tử' quote'. Điều này có vẻ kỳ quặc. Có đúng không? Vui lòng xác nhận. –

+0

Đó là ý định, vâng. – Tench

Trả lời

1

Đây là giải pháp thay thế. Nó cho phép một tài liệu đầu vào phong cách tường thuật hơn (dấu ngoặc kép trong dấu ngoặc kép, nhiều đoạn (Nguồn) trong một nút văn bản, '„' làm dữ liệu khi không theo sau bởi phần tử hi).

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:so="http://stackoverflow.com/questions/12690177" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="xsl xs so"> 
<xsl:output omit-xml-declaration="yes" indent="yes" /> 
<xsl:strip-space elements="*" /> 

<xsl:template match="@*|comment()|processing-instruction()"> 
    <xsl:copy /> 
</xsl:template> 

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

<xsl:function name="so:clip-start" as="xs:string"> 
    <xsl:param name="in-text" as="xs:string" /> 
    <xsl:value-of select="substring($in-text,1,string-length($in-text)-1)" /> 
</xsl:function> 

<xsl:function name="so:clip-end" as="xs:string"> 
    <xsl:param name="in-text" as="xs:string" /> 
    <xsl:value-of select="substring-after($in-text,'”')" /> 
</xsl:function> 

<xsl:function name="so:matches-start" as="xs:boolean"> 
    <xsl:param name="text-node" as="text()" /> 
    <xsl:value-of select="$text-node/following-sibling::node()/self::hi[@rend='italics'] and 
         ends-with($text-node, '„')" /> 
</xsl:function> 

<xsl:template match="text()[so:matches-start(.)]" priority="2"> 
    <xsl:call-template name="parse-text"> 
    <xsl:with-param name="text" select="so:clip-start(.)" /> 
    </xsl:call-template> 
</xsl:template> 

<xsl:function name="so:matches-end" as="xs:boolean"> 
    <xsl:param name="text-node" as="text()" /> 
    <xsl:value-of select="$text-node/preceding-sibling::node()/self::hi[@rend='italics'] and 
         matches($text-node,'^[!?]*”')" /> 
</xsl:function> 

<xsl:template match="text()[so:matches-end(.)]" priority="2"> 
    <xsl:call-template name="parse-text"> 
    <xsl:with-param name="text" select="so:clip-end(.)" /> 
    </xsl:call-template> 
</xsl:template> 

<xsl:template match="text()[so:matches-start(.)][so:matches-end(.)]" priority="3"> 
    <xsl:call-template name="parse-text"> 
    <xsl:with-param name="text" select="so:clip-end(so:clip-start(.))" /> 
    </xsl:call-template> 
</xsl:template> 

<xsl:template match="text()" name="parse-text" priority="1"> 
    <xsl:param name="text" select="." /> 
    <xsl:analyze-string select="$text" regex="\(([^)]*)\)"> 
    <xsl:matching-substring> 
     <source> 
     <xsl:value-of select="regex-group(1)" /> 
     </source> 
    </xsl:matching-substring> 
    <xsl:non-matching-substring> 
     <xsl:value-of select="." /> 
    </xsl:non-matching-substring> 
    </xsl:analyze-string> 
</xsl:template> 

<xsl:template match="hi[@rend='italics']"> 
    <quote> 
    <xsl:apply-templates select="(@* except @rend) | node()" /> 
    <xsl:for-each select="following-sibling::node()[1]/self::text()[matches(.,'^[!?]')]"> 
     <xsl:value-of select="replace(., '^([!?]+).*$', '$1')" /> 
    </xsl:for-each> 
    </quote> 
</xsl:template> 

</xsl:stylesheet> 
2

chuyển đổi này:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes"/> 

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

<xsl:template match= 
    "hi[@rend='italics' 
    and 
     preceding-sibling::node()[1][self::text()[ends-with(., '„')]] 
     ]"> 

    <quote> 
    <xsl:value-of select= 
    "concat(., 
      if(matches(following-sibling::text()[1], '^[?!]+')) 
       then replace(following-sibling::text()[1], '^([?!]+).*$', '$1') 
       else() 
      ) 
     "/> 
    </quote> 
</xsl:template> 

<xsl:template match="text()[true()]"> 
    <xsl:variable name="vThis" select="."/> 
    <xsl:variable name="vThis2" select="translate($vThis, '„”?!', '')"/> 

    <xsl:value-of select="substring-before(concat($vThis2, '('), '(')"/> 
    <xsl:if test="contains($vThis2, '(')"> 
    <source> 
    <xsl:value-of select= 
     "substring-before(substring-after($vThis2, '('), ')')"/> 
    </source> 
    <xsl:value-of select="substring-after($vThis2, ')')"/> 
    </xsl:if> 
</xsl:template> 
</xsl:stylesheet> 

khi áp dụng trên tài liệu XML cung cấp:

<root> 
     <p> 
      <element>This one is taken care of.</element> Some more text. „<hi rend="italics">Is this a 
       quote</hi>?” (Source). </p> 

     <p> 
      <element>This one is taken care of.</element> Some more text. „<hi rend="italics">This is a 
       quote</hi>” (Source). </p> 

     <p> 
      <element>This one is taken care of.</element> Some more text. „<hi rend="italics">This is 
       definitely a quote</hi>!” (Source). </p> 

     <p> 
      <element>This one is taken care of.</element> Some more text.„<hi rend="italics">This is a 
       first quote</hi>” (Source). „<hi rend="italics">Sometimes there is a second quote as 
       well</hi>!?” (Source). </p> 

</root> 

sản xuất mong muốn, đúng kết quả:

<root> 
     <p> 
      <element>This one is taken care of.</element> Some more text. <quote>Is this a 
       quote?</quote> <source>Source</source>. </p> 

     <p> 
      <element>This one is taken care of.</element> Some more text. <quote>This is a 
       quote</quote> <source>Source</source>. </p> 

     <p> 
      <element>This one is taken care of.</element> Some more text. <quote>This is 
       definitely a quote!</quote> <source>Source</source>. </p> 

     <p> 
      <element>This one is taken care of.</element> Some more text.<quote>This is a 
       first quote</quote> <source>Source</source>. <quote>Sometimes there is a second quote as 
       well!?</quote> <source>Source</source>. </p> 

</root> 
+0

+1. Tôi nghĩ, XSLT 2.0 đã cho, để thay thế văn bản của '(Nguồn)' bằng ' Nguồn' trong các nút văn bản, tôi muốn sử dụng 'phân tích-chuỗi'. Và tôi tự hỏi liệu tất cả các ký tự trích dẫn và dấu chấm câu trong các nút văn bản có thể đơn giản được loại bỏ hay không, hoặc chúng chỉ cần xóa khi xảy ra ngay trước hoặc sau hoặc giữa các phần tử 'hi' đó. –

+0

Trên Saxon, điều này ném rất nhiều lỗi có thể phục hồi: kết hợp quy tắc không rõ ràng cho văn bản(). –

+0

@MartinHonnen, Có, 'xsl: analysis-string' là tốt đẹp và tôi sẽ sử dụng nó nếu vấn đề phức tạp hơn.Đối với vị trí của các ký tự cần xóa, điều này không rõ ràng từ câu hỏi hiện tại - có thể dễ dàng thực hiện trong mọi trường hợp. Mục đích của tôi là đưa ra một giải pháp ngắn - tôi nghĩ vậy. –

Các vấn đề liên quan