使用xslt重新格式化xml文件并保留精确格式

时间:2016-04-03 11:21:17

标签: php xml xslt formatting line-breaks

我有一个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>

我有一个复杂的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. 我可以在给定元素中的子节点之间换行(因此可以逻辑分组)吗?
  3. 我通过php形成上述xml。一旦我有了xml,我希望它的格式如上所述。我可以使用php字符串,但它是一个巨大的文件,这样做是相当繁琐的。 xsl可以用来解决这个问题吗?

    如何实现这一点的任何指示将非常感激。 THX

3 个答案:

答案 0 :(得分:1)

我不知道任何XML序列化程序(基于XSLT或其他)可以让您对一组属性的格式进行一定程度的控制,尽管您可以通过利用saxon:attribute-order和saxon:xsl:output上的line-length属性:请参阅http://www.saxonica.com/documentation/index.html#!extensions/output-extras/serialization-parameters

目前尚不清楚为什么您当前的代码会出错,但由于您还没有告诉我们错误是什么,我不会尝试回答问题的这一部分。< / p>

答案 1 :(得分: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>

答案 2 :(得分:0)

<?php

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

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

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



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