2011-05-25 20 views
7

से कई फ़ाइलों को ट्रांसफॉर्म करें मैंने एक एक्सएसएलटी फ़ाइल बनाई है जो एक एक्सएमएल फ़ाइल को बदल सकती है। हालांकि, मेरे पास एकाधिक एक्सएमएल फाइलों के साथ कई सौ निर्देशिकाएं हैं। इन सभी फ़ाइलों को बदलने के लिए एक्सएसएलटी में कोई तरीका है। मैं सभी फाइलों की सूची प्राप्त करने के लिए संग्रह फ़ंक्शन का उपयोग कर रहा हूं। लेकिन, सुनिश्चित नहीं है कि अब ट्रांसफॉर्म को कैसे लागू करें।एक्सएसएलटी उपनिर्देशिका

मेरा उदाहरण एक्सएसएलटी फ़ाइल है। असल में, मैं सभी एक्सएमएल फाइलों के माध्यम से लूप करना चाहता हूं और व्यक्तिगत फ़ाइल पर टेम्पलेट टेबल लागू करना चाहता हूं। इन सभी परिवर्तनों का उत्पादन एक एकल फ्लैट टेक्स्ट फ़ाइल में होना चाहिए।

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:foo="http://whatever"> 

<xsl:output method="text" encoding="ISO-8859-1"/> 
    <xsl:template name="process"> 
     <xsl:variable name="files" select="collection('file:///C:/files/testResults?select=*.xml;recurse=yes')"/> 
     <xsl:for-each select="$files"> 
      <xsl:if test="(not(contains(document-uri(.), 'SuiteSetUp'))) and (not(contains(document-uri(.), 'SuiteTearDown')))"> 
       <xsl:value-of select="tokenize(document-uri(.), '/')[last()]"></xsl:value-of> 
       <xsl:apply-templates select="/testResults/result/tables/table[14]"> 
        <xsl:with-param name="title" select="/testResults/rootPath"></xsl:with-param> 
       </xsl:apply-templates> 
       <xsl:apply-templates select="/testResults/result/tables/table[15]"/> 
      </xsl:if> 
     </xsl:for-each> 
    </xsl:template> 

    <xsl:template match="table"> 
    <xsl:param name="testName"></xsl:param> 
     <xsl:for-each select="row"> 
      <xsl:if test="position() > 2"> 
       <xsl:variable name="choices" select="col[2]"></xsl:variable> 
       <xsl:if test="contains($choices, 'fail')"> 
        <xsl:value-of select="$testName"></xsl:value-of> 
        <xsl:text>|</xsl:text> 
        <xsl:value-of select="col[1]"></xsl:value-of> 
        <xsl:text>|</xsl:text> 
        <xsl:value-of select="foo:getCorrectChoices(col[2])"></xsl:value-of> 
        <xsl:text>|</xsl:text> 
        <xsl:value-of select="foo:getExpectedChoices(col[2])"></xsl:value-of> 
        <xsl:text>|</xsl:text> 
        <xsl:call-template name="NewLine"/> 
       </xsl:if> 
      </xsl:if> 
     </xsl:for-each> 
    </xsl:template> 

    <xsl:template name="NewLine"> 
     <xsl:text>&#xA;</xsl:text> 
    </xsl:template> 

    <xsl:function name="foo:getCorrectChoices"> 
     <xsl:param name="content"></xsl:param> 
     <xsl:analyze-string select="$content" regex="\[(\[.+?\])\] fail"> 
      <xsl:matching-substring> 
       <xsl:value-of select="regex-group(1)"></xsl:value-of> 
      </xsl:matching-substring> 
     </xsl:analyze-string> 
    </xsl:function> 
    <xsl:function name="foo:getExpectedChoices"> 
     <xsl:param name="content"></xsl:param> 
     <xsl:analyze-string select="$content" regex="fail\(expected \[(\[.+?\])\]"> 
      <xsl:matching-substring> 
       <xsl:value-of select="regex-group(1)"></xsl:value-of> 
      </xsl:matching-substring> 
     </xsl:analyze-string> 
    </xsl:function> 
</xsl:stylesheet> 
+0

आप किस प्रकार का एक्सएसएलटी प्रोसेसर उपयोग कर रहे हैं? यदि आप सैक्सन का उपयोग कर रहे हैं, तो आप इसे सीधे कमांड लाइन से कर सकते हैं। सैक्सन उन फ़ाइलों के बैच को बदलने में सक्षम है जिसके लिए आप एक ही ट्रांसफॉर्म लागू करना चाहते हैं। –

+0

मैं अपने एक्सएसएलटी बनाने के लिए एडिटएक्स नामक एक एक्सएसएलटी संपादक का उपयोग कर रहा था और सोचा कि शायद मैं इसे वहां से चला सकता हूं। लेकिन ऐसा लगता है कि मुझे इसे कहीं और चलाने की ज़रूरत है। मैंने एक्सएसएलटी के लिए एक चींटी कार्य देखा। क्या वह काम करेगा? – user320587

+0

आप किस ऑपरेटिंग सिस्टम पर चल रहे हैं? –

उत्तर

7

यहाँ शायद सबसे सरल उदाहरण (सेक्सन में लागू किया collection() समारोह का उपयोग करके) कैसे एक फाइल सिस्टम सबट्री में सभी एक्सएमएल फ़ाइलों को प्रोसेस करने के लिए है:

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

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

<xsl:template match="/"> 
    <xsl:apply-templates mode="inFile" select= 
    "collection('file:///C:/temp?select=*.xml;recurse=yes')"/> 
</xsl:template> 
</xsl:stylesheet> 

जब किसी XML दस्तावेज़ पर लागू (उपयोग नहीं किया गया, अनदेखा किया गया), यह परिवर्तन फ़ाइल सिस्टम के C:/Temp उपट्री में *.xml फ़ाइलों में शामिल प्रत्येक XML दस्तावेज़ में पहचान नियम लागू करता है।

अधिक नैनिंग प्रसंस्करण करने के लिए, inFile मोड में पहचान टेम्पलेट को ओवरराइड करने की आवश्यकता है।

अपने विशिष्ट मामले में मेरा मानना ​​है कि आप बस की जगह ले सकता:

  <xsl:apply-templates select="./testResults/result/tables/table[14]">  

साथ

  <xsl:apply-templates select="/testResults/result/tables/table[14]">  

और इस नोड पर वांछित टेम्पलेट्स बंद चयनित वर्तमान (दस्तावेज़) लागू होता है नोड।

+0

मुझे त्रुटि मिल रही है "संग्रह एक अज्ञात xslt फ़ंक्शन है" जब मैं इसे C# में बदलता हूं। कृपया मेरी मदद करें – shanmugharaj

+0

@shansfk, हां, एक्सएसएलटी इंजन जो .NET के साथ आते हैं XSLT 2.0 का समर्थन नहीं करते हैं। सवाल यह है कि एक्सएसएलटी 2.0 में ऐसा कैसे करें - जैसा कि ओपी कोड द्वारा प्रदान किया गया है। आप सैक्सन.NET को स्थापित और उपयोग कर सकते हैं और फिर यह परिवर्तन अपेक्षित परिणाम देगा। –

0

मैं सिर्फ दिमित्री के उत्कृष्ट उत्तर का हल्का संस्करण जोड़ना चाहता था। आप <foo> दस्तावेजों (रूट नोड) एक निर्देशिका में बैठे, और <foo> के लिए एक काम XSLT कार्यक्रम है, तो बस इस तरह अपने उच्च-स्तरीय टेम्पलेट बनाने:

<xsl:template match="/"> 
    <xsl:apply-templates select="collection($my_url)/foo"/> 
</xsl:template> 

संभालने है कि आप एक पैरामीटर के रूप में यूआरएल चाहते हैं, <xsl:param name="my_url"/> , कमांड लाइन पर निर्दिष्ट है।