2016-04-03 57 views
1

我有一個xml文件需要以特定方式格式化以確保可讀性。使用xslt重新格式化xml文件並保留確切格式

源XML

<?xml version="1.0" encoding="UTF-8"?> 
<facility> 
<attributes> 
    <id>1</id> 
    <name>Facility Name</name> 
    <coordinate>Lat,Long</coordinate> 
    <projection>mercator</projection> 
    <units>imperial</units> 
    <showcart>yes</showcart> 
    <shotplanner>yes</shotplanner> 
    <sound>on</sound> 
    <gfbkgcolor>#ff0000</gfbkgcolor> 
    <gftxtcolor>#ffffff</gftxtcolor> 
    <gcbkgcolor>#ffffff</gcbkgcolor> 
    <gctxtcolor>#000000</gctxtcolor> 
</attributes> 
</facility> 

期望輸出

<facility name="Facility Name" id="1" 
      coordinate="Lat,Long" projection="mercator" 
      units="imperial" showcart="yes" shotplanner="yes" 
      sound="on" gfbkgcolor="#ff0000" gftxtcolor="#ffffff" 
      gcbkgcolor="#ffffff"> 
</facility> 

Ive得到了一個複雜的XML文件,但是那幾乎是我想要做的事。

XSL模板

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" indent="yes"/> 
<xsl:template match="/"> 
    <xsl:for-each select="facility/attributes"> 
     <facility id="{id}" name="{name}" 
        coordinate="{coordinate}"> 
     </facility> 
     <xsl:text>&#xA;</xsl:text> 
     <test>"hello"</test> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

使用此<xsl:text>&#xA;</xsl:text>似乎拋出一個錯誤,並且不顯示輸出XML。

  1. 是否有可能在使用xsl的某些屬性之後出現換行符?
  2. 我可以在給定元素中的兒童之間有換行符(所以他們可以按邏輯分組)?

我正在通過php形成上述xml。一旦我有了這個xml,我希望它能像上面提到的那樣格式化。我可以使用PHP字符串來完成它,但它是一個巨大的文件,並且這樣做會非常繁瑣。 xsl可以用來解決這個問題嗎?

任何關於如何實現這一點的指針將不勝感激。 Thx

+1

你需要了解的是XSLT的處理模型接受一個輸入樹並將其轉換爲具有元素節點與屬性節點的結果樹而屬性的任何格式和在創建結果樹之後,它們之間的空間是可選的序列化步驟。因此,某些屬性之間的換行符不是XSLT轉換創建的內容,它將成爲序列化的一部分。 XSLT 1.0定義的序列化選項不提供任何屬性之間換行符的設置。 –

+0

所以實現這個輸出的唯一方法就是用正確的格式將它寫出到一個使用php的文件中? – Karthik

+0

要將'attributes'元素的子元素轉換爲屬性,您可以優雅地使用XSLT,但爲了強制執行特定的屬性格式化,您需要查看XSLT處理器的序列化選項,或者自己實現序列化,無論是PHP還是XSLT (如http://lenzconsulting.com/xml-to-string/)。 –

回答

0

作爲PHP是一種通用語言,並配備了XSLT 1。0處理器,你可以在一個腳本處理這兩種操作,XML轉換和文本格式,:

XSLT腳本(保存在外部被加載低於或添加爲loadXML的嵌入式字符串())

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:output version="1.0" encoding="UTF-8" indent="yes" /> 
<xsl:strip-space elements="*"/> 

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

    <!-- Migrate Nodes to Attributes --> 
    <xsl:template match="attributes/*">  
     <xsl:attribute name="{name()}"> 
     <xsl:value-of select="."/> 
     </xsl:attribute> 
    </xsl:template> 

</xsl:transform> 

PHP腳本

<?php 

// Load the XML source and XSLT file 
$doc = new DOMDocument(); 
$doc->load('Source.xml'); 

$xsl = new DOMDocument; 
$xsl->load('XSLTScript.xsl'); 

// Configure the processor 
$proc = new XSLTProcessor; 
$proc->importStyleSheet($xsl); 

// Transform XML source 
$newXml = $proc->transformToXML($doc); 

// Add line breaks, tabs, and spaces between attributes to output string 
$newXml = str_replace("coordinate", "\n\t\t coordinate", $newXml); 
$newXml = str_replace("units", "\n\t\t units", $newXml); 
$newXml = str_replace("sound", "\n\t\t sound", $newXml); 
$newXml = str_replace("gcbkgcolor", "\n\t\t gcbkgcolor", $newXml); 
$newXml = str_replace("/>", ">\n</facility>", $newXml); 

echo $newXml; 

// Save output to file 
$xmlfile = 'Output.xml'; 
file_put_contents($xmlfile, $newXml); 

?> 

輸出

<?xml version="1.0" encoding="UTF-8"?> 
<facility id="1" name="Facility Name" 
      coordinate="Lat,Long" projection="mercator" 
      units="imperial" showcart="yes" shotplanner="yes" 
      sound="on" gfbkgcolor="#ff0000" gftxtcolor="#ffffff" 
      gcbkgcolor="#ffffff" gctxtcolor="#000000"> 
</facility> 
+0

很好,你在那裏做了什麼,我結束了通過PHP做它,因爲我的源代碼是一個PHP數組反正。發佈我做過的一小部分。 – Karthik

0

<?php 
 

 
public function writeToXml(){ 
 
\t \t $data = array(
 
\t \t \t "id"   => 15, 
 
\t \t \t "name"  => "Facility Name", 
 
\t \t \t "coordinate" => "Lat,lon", 
 
\t \t \t "projection" => "mercator", 
 
\t \t \t "units"  => "imperial", 
 
\t \t \t "showcart" => "yes", 
 
\t \t \t "shotplanner" => "yes", 
 
\t \t \t "sound"  => "on", 
 
\t \t \t "gfbkgcolor" => "#ff0000", 
 
\t \t \t "gftxtcolor" => "#ffffff", 
 
\t \t \t "gcbkgcolor" => "#ffffff", 
 
\t \t \t "gctxtcolor" => "#000000", 
 
\t \t \t "gbbkgcolor" => "#0000ff", 
 
\t \t \t "gbtxtcolor" => "#ffffff" 
 
\t \t); 
 

 
    // Inserts a new line with a specified indent 
 
\t function insertNewLine($indent = 0){ 
 
\t \t $line = "\n"; 
 
\t \t $line .= str_repeat("\t", $indent); 
 
\t \t return $line; 
 
\t } 
 
    
 
    // Formats a given string with a trailing space 
 
\t function formatString($string) { 
 
\t \t $data = "\"" . $string . "\" "; 
 
\t \t return $data; 
 
\t } 
 

 
\t $facility = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"; 
 
\t $facility .= insertNewLine(); 
 
\t $facility .= "<facility name=" . formatString($data['name']); 
 
\t $facility .= "coordinate=" . formatString($data["coordinate"]); 
 
\t $facility .= insertNewLine(1); 
 
\t $facility .= "projection=" . formatString($data['projection']); 
 
\t $facility .= "units=" . formatString($data['units']); 
 
\t $facility .= "showcart=" . formatString($data['showcart']); 
 
\t $facility .= "shotplanner=" . formatString($data['shotplanner']); 
 
\t $facility .= "sound=" . formatString($data['sound']); 
 
\t $facility .= insertNewLine(1); 
 
\t $facility .= "gfbkgcolor=" . formatString($data['gfbkgcolor']); 
 
\t $facility .= "gftxtcolor=" . formatString($data['gftxtcolor']); 
 
\t $facility .= insertNewLine(1); 
 
\t $facility .= "gcbkgcolor=" . formatString($data['gcbkgcolor']); 
 
\t $facility .= "gctxtcolor=" . formatString($data['gctxtcolor']); 
 
\t $facility .= "/>"; 
 

 

 

 
\t $myfile = fopen('application/packages/myfile.txt', 'w+'); 
 
\t fwrite($myfile, $facility); 
 
\t fclose($myfile); 
 
\t // echo $facility; 
 
});

+0

又一種方式!但是,由於PHP自帶[DOM類方法](http://php.net/manual/en/class.domdocument.php),因此不需要連接XML內容:'createElement()','setAttribute() ','appendChild()'... – Parfait