XSLt.transform дает мне «ď» ż » - PullRequest
3 голосов
/ 07 мая 2010

У меня есть XML:

<results>
    <Countries country="Albania">
        <Regions region="Centralna Albania">
            <Provinces province="Durres i okolice">
                <Cities city="Durres"
                            cityCode="2B66E0ACFAEF78734E3AF1194BFA6F8DEC4C5760">
                    <IndividualFlagsWithForObjects Status="1" />
                    <IndividualFlagsWithForObjects  Status="0" />
                    <IndividualFlagsWithForObjects status="2" />
                 </Cities>
             </Provinces>
        </Regions>
    </Countries>
    <Countries .... 

Что является результатом этой части запроса:

SELECT Countries.FileSystemName as country,
       Regions.DefaultName as region ,
       Provinces.DefaultName as province,
       cities.defaultname as city,
       cities.code as cityCode, 
       IndividualFlagsWithForObjects.value as Status

У меня есть xslt:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" encoding="iso-8859-1"/>

  <xsl:param name="delim" select="string(',')" />
  <xsl:param name="quote" select="string('&quot;')" />
  <xsl:param name="break" select="string('&#xD;')" />

  <xsl:template match="/">
    <xsl:apply-templates select="results/countries" />
  </xsl:template>

  <xsl:template match="countries">
    <xsl:apply-templates />
    <xsl:if test="following-sibling::*">
      <xsl:value-of select="$break" />
    </xsl:if>
  </xsl:template>

  <xsl:template match="*">
    <!-- remove normalize-space() if you want keep white-space at it is -->
    <xsl:value-of select="concat($quote, normalize-space(.), $quote)" />
    <xsl:if test="following-sibling::*">
      <xsl:value-of select="$delim" />
    </xsl:if>
  </xsl:template>

  <xsl:template match="text()" />
</xsl:stylesheet>

И является частьюс кодом

XmlReader reader = cmd.ExecuteXmlReader();

doc.LoadXml("<results></results>");
XmlNode newNode = doc.ReadNode(reader);

while (newNode != null)
{
    doc.DocumentElement.AppendChild(newNode);
    newNode = doc.ReadNode(reader);
}                    

doc.Save(@"c:\listOfCities.xml");

XslCompiledTransform XSLT = new XslCompiledTransform();    
XsltSettings settings = new XsltSettings();    


XSLT.Load(@"c:\xsltfile1.xslt", settings, new XmlUrlResolver());

XSLT.Transform(doc.OuterXml,@"c:\myCities.csv");

Почему сейчас у меня в моей csv только одна ячейка со значением: ď »ż

Ответы [ 7 ]

1 голос
/ 17 мая 2010

Ваша выходная кодировка установлена ​​на encoding = "iso-8859-1", но эта кодовая страница ISO не содержит символов, которые вы упомянули. Например, defined определяется только в iso-8859-2.

Поэтому я предполагаю, что проблема вызвана несоответствием кодировок. Посмотрите на сгенерированный файл в шестнадцатеричном редакторе.

Я не уверен, использует ли метод XslCompiledTransform.Transform кодировку, указанную в XSLT для записи файла.

Используйте метод Transform (), который пишет в XmlWriter на основе StringBuilder и сохраните полученную строку в файл, управляющий ее кодировкой.

1 голос
/ 17 мая 2010

ď »ż - это то, с чего начинают файлы UTF8 для приложений, не поддерживающих UTF8. Ваш Xml Writer выводит Unicode, но результат должен быть ISO-8859-1 (согласно <xsl:output method="text" encoding="iso-8859-1"/>

при звонке XSLT.Transform (...) в вашем коде, используйте перегрузку Transform(String, XmlWriter) и создайте этот XmlWriter с кодировкой ISO-8859-1:

XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8;

XmlWriter writer = XmlWriter.Create("c:\myCities.csv",settings);

, а затем использовать его для преобразования

XSLT.Transform(doc.OuterXml,writer);
1 голос
/ 16 мая 2010

Входной xml (или xslt), вероятно, начинается с метки порядка байтов Unicode и плохо анализируется c # (без очевидной причины, которую я могу найти ..).

Откройте его в каком-нибудь гекседиторе, посмотрите первые 3 байта и удалите их.

1 голос
/ 15 мая 2010

Похоже, вы используете неправильный набор символов. Это отличная ссылка, которую вы действительно должны прочитать: http://www.joelonsoftware.com/articles/Unicode.html

Как гласит заголовок, это «Абсолютный минимум, который должен знать каждый разработчик программного обеспечения, абсолютно положительно знающий о Unicode и наборах символов (никаких оправданий!)».

1 голос
/ 11 мая 2010

XML-элементы называются Countries, а XSLT использует countries вместо.

Я бы также сделал явной обработку элементов и атрибутов:

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

  <xsl:output method="text" encoding="iso-8859-1"/> 

  <xsl:param name="delim" select="string(',')" /> 
  <xsl:param name="quote" select="string('&quot;')" /> 
  <xsl:param name="break" select="string('&#xD;')" /> 

  <xsl:template match="/"> 
    <xsl:apply-templates select="results/Countries" /> 
  </xsl:template> 

  <xsl:template match="Countries"> 
    <xsl:apply-templates select="@*|*"/> 
    <xsl:if test="following-sibling::*"> 
      <xsl:value-of select="$break" /> 
    </xsl:if> 
  </xsl:template> 

  <xsl:template match="*"> 
    <xsl:apply-templates select="@*"/> 
    <xsl:if test="*|following-sibling::*"> 
      <xsl:value-of select="$delim" /> 
      <xsl:apply-templates select="*"/> 
    </xsl:if> 
  </xsl:template> 

  <xsl:template match="@*"> 
    <!-- remove normalize-space() if you want keep white-space at it is --> 
    <xsl:value-of select="concat($quote, normalize-space(.), $quote)" /> 
    <xsl:if test="position() != last ()"> 
      <xsl:value-of select="$delim" /> 
    </xsl:if> 
  </xsl:template> 

</xsl:stylesheet>
0 голосов
/ 17 мая 2010

Я думаю, это то, что вы хотели сделать. Я рекомендую вам взглянуть на предложение xslt от Dour High Arch. Это сделало бы вещи чище.

код C #

XslCompiledTransform style = new XslCompiledTransform();
style.Load(@"c:\xsltfile1.xslt");
style.Transform(@"c:\listOfCities.xml", @"c:\myCities.csv");

xsltfile1.xslt

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" encoding="iso-8859-1"/>

  <xsl:param name="delim" select="string(',')" />
  <xsl:param name="quote" select="string('&quot;')" />
  <xsl:param name="break" select="string('&#xD;')" />

  <xsl:template match="/">
    <xsl:apply-templates select="results/Countries" />
  </xsl:template>

  <xsl:template match="Countries">
    <xsl:apply-templates select="//@*" />
    <xsl:if test="not(position()=last())">
      <xsl:value-of select="$break" />
    </xsl:if>
  </xsl:template>

  <xsl:template match="@*">
    <xsl:value-of select="concat($quote, normalize-space(.), $quote)" />
    <xsl:if test="not(position()=last())">
      <xsl:value-of select="$delim" />
    </xsl:if>
  </xsl:template>

  <xsl:template match="text()" />
</xsl:stylesheet>

listOfCities.csv:

"Albania","Centralna Albania","Durres i okolice","Durres","2B66E0ACFAEF78734E3AF1194BFA6F8DEC4C5760","1","0","2"
0 голосов
/ 12 мая 2010

Я не могу понять, что должна делать эта таблица стилей. EnableScript = true тоже не имеет смысла. Попробуйте это:

string folderPath = @"path\to\your\folder";
using (XmlReader reader = XmlReader.Create(Path.Combine(folderPath, "listOfCities.xml")))
using (TextWriter writer = File.CreateText(Path.Combine(folderPath, "myCities.csv")))
{
    var xslt = new XslCompiledTransform();
    xslt.Load(Path.Combine(folderPath, "citiesCsv.xslt"));
    xslt.Transform(reader, null, writer);
}

Где города Csv.xslt:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <xsl:template match="/">
    <xsl:for-each select="//Countries">
      <xsl:value-of
        select="@country"/>,<xsl:value-of
        select="Regions/@region"/>,<xsl:value-of
        select="Regions/Provinces/@province"/>,<xsl:value-of
        select="Regions/Provinces/Cities/@city"/>
      <xsl:text>&#13;&#10;</xsl:text>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...