2016-04-03 53 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