2012-06-29 5 views
2

샘플 XML의 반복 그룹을 두 개의 구분 된 텍스트 줄로 변환하려고했습니다.반복 그룹을 여러 텍스트 줄로 변환

string orderXml = 
@"<?xml version='1.0' encoding='utf-8'?> 
<Order id='79223510'> 
<Status>new</Status> 
<ShipMethod>Standard International</ShipMethod> 
<ToCity>Tokyo</ToCity> 
<Items> 
    <Item> 
    <SKU>SKU-1234567890</SKU> 
    <Quantity>1</Quantity> 
    <Price>99.95</Price> 
    </Item> 
    <Item> 
    <SKU>SKU-1234567899</SKU> 
    <Quantity>1</Quantity> 
    <Price>199.95</Price> 
    </Item> 
</Items> 
</Order>"; 

StringReader str = new StringReader(orderXml); 

var xslt = new XmlTextReader(new StringReader(
@"<?xml version='1.0' encoding='UTF-8'?>" + 
"<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>" + 

"<xsl:output method='text' indent='no'/>" + 

"<!-- New line character variable -->" + 
"<xsl:variable name='newline'>" + 
"<xsl:text>&#13;&#10;</xsl:text>" + 
"</xsl:variable>" + 
"<xsl:variable name='empty'>" + 
"<xsl:text></xsl:text>" + 
"</xsl:variable>" + 

"<xsl:template match='/'>" +   

"<xsl:for-each select='Order'>" + 
"<xsl:value-of select='@id'/>|" + 
"<xsl:value-of select='Status'/>|" + 
"<xsl:value-of select='ShipMetod'/>|" + 
"<xsl:value-of select='ToCity'/>|" + 
"<xsl:value-of select='$newline'/>" + 
"</xsl:for-each>" + 

"<xsl:for-each select='Order/Items/Item'>" + 
"<xsl:value-of select='SKU'/>|" +   
"<xsl:value-of select='Quantity'/>|" + 
"<xsl:value-of select='Price'/>|" +  
"<xsl:value-of select='$newline'/>" + 
"</xsl:for-each>" + 

"</xsl:template>" + 
"</xsl:stylesheet>" 
       )); 

var xDoc = new XPathDocument(str); 
var xTr = new System.Xml.Xsl.XslCompiledTransform(); 
xTr.Load(xslt); 

StringBuilder sb = new StringBuilder(); 
StringWriter writer = new StringWriter(sb); 
xTr.Transform(xDoc, null, writer); 

string[] lines = sb.ToString().Split(new string[] {"\n"}, StringSplitOptions.RemoveEmptyEntries);  

lines.ToList().ForEach(System.Console.Write);  

이 코드는 현재 다음과 같은 출력을 생성합니다 : 여기에 내 현재 코드 버전입니다

79223510|new||Tokyo| 
SKU-1234567890|1|99.95| 
SKU-1234567899|1|199.95| 

와 나는 그것을 생산하기 위해 다음과 같은 하나 원 : 그냥 XSL을 사용하여

79223510|new||Tokyo|SKU-1234567890|1|99.95| 
79223510|new||Tokyo|SKU-1234567899|1|199.95| 

을 변환. 제발 조언.

P. 쉽게 읽기위한 텍스트 형태로 추가 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='text' indent='no'/> 

<!-- New line character variable --> 
<xsl:variable name='newline'> 
<xsl:text>&#13;&#10;</xsl:text> 
</xsl:variable> 
<xsl:variable name='empty'> 
<xsl:text></xsl:text> 
</xsl:variable> 

<xsl:template match='/'>   

<xsl:for-each select='Order'> 
<xsl:value-of select='@id'/>| 
<xsl:value-of select='Status'/>| 
<xsl:value-of select='ShipMetod'/>| 
<xsl:value-of select='ToCity'/>| 
<xsl:value-of select='$newline'/> 
</xsl:for-each> 

<xsl:for-each select='Order/Items/Item'> 
<xsl:value-of select='SKU'/>|   
<xsl:value-of select='Quantity'/>| 
<xsl:value-of select='Price'/>|  
<xsl:value-of select='$newline'/> 
</xsl:for-each> 

</xsl:template> 
</xsl:stylesheet> 

답변

2

당신이 만들고있는 몇 가지 실수 : 당신은 두 개의 분리를위한 각 루프보다는 루프에서 루프를 사용하는

  1. , 그래서 첫 번째 출력 행은 Order 요소에서 발생하며 다음 두 요소는 Item 요소에서 발생합니다. (실제로는 루프가 필요 없습니다. 아래의 솔루션을 참조하십시오.)
  2. ShipMetod의 맞춤법 오류로 인해 필드 중 하나가 실수로 비어 있습니다.
  3. 필드 값에 나타날 수있는 | 값을 이스케이프 처리하는 방법이 없습니다. (내 솔루션은 당신이 그것에 대해 무엇을하고 싶은지 모르므로이 문제를 해결하지 못합니다.)

더 좋은 해결책은 템플릿 매칭과 문자열 연결을 사용하는 것입니다.

<xsl:stylesheet version="1.0" xmlns:xsl='http://www.w3.org/1999/XSL/Transform'> 
<xsl:output method="text" indent="no" media-type="text/plain" /> 

<xsl:variable name='newline'><xsl:text>&#13;&#10;</xsl:text></xsl:variable> 
<xsl:variable name='delimiter'>|</xsl:variable> 

<!-- by default, don't copy any nodes to output --> 
<xsl:template match="node()|@*"><xsl:apply-templates select="node()|@*"/></xsl:template> 

<xsl:template match="/Order/Items/Item"><xsl:value-of 
select="concat(
../../@id, $delimiter, 
../../Status, $delimiter, 
../../ShipMethod, $delimiter, 
../../ToCity, $delimiter, 
SKU, $delimiter, 
Quantity, $delimiter, 
Price, $delimiter, 
$newline)"/></xsl:template> 

</xsl:stylesheet> 

이 다음과 같은 출력이 생성

79223510|new|Standard International|Tokyo|SKU-1234567890|1|99.95| 
79223510|new|Standard International|Tokyo|SKU-1234567890|1|199.95| 
+0

네, 해결책은 아주 잘 작동을! 문제가 해결되었습니다. 고맙습니다. – ShamilS

관련 문제