根据root-tag

时间:2016-07-04 09:47:16

标签: c# xslt xmlreader

我有一个我想读的xml文件。根据root-tag我之前正在进行xsl-transform并读取修改后的文件:

XmlReader reader = XmlReader.Create(myFile);

var root = new XmlDocument();
root.Load(reader);
if (root.DocumentElement.Name == "FC_FeatureCatalogue")
{
    var xsltDoc = new XmlDocument();
    xsltDoc.Load("myXslt.xsl"));

    XsltSettings xsltSettings = new XsltSettings(false, true);
    var transformer = new XslCompiledTransform();
    transformer.Load(xsltDoc, xsltSettings, new XmlUrlResolver());

    using (var stream = new FileStream(newFileName, FileMode.Create))
    {
        transformer.Transform(reader, new XsltArgumentList(), stream);
    }
}

当条件通过时,创建由newFileName确定的文件。但它只包含一个空条目。所以我调试了一下,注意到在调用root.Load(reader)时,文件被读取直到EOF。这就是为什么我假设当使用相同的文件进行转换时,变换器根本没有做什么,因为读者没有其他内容。

那么有没有办法重新设置读者(我知道,XmlReader是“仅向前”)或者替代地获取原始xml文件的根标签而不读取EOF和改造它?

编辑:为了验证我的假设,我还在我的using - 块中添加了这些行:

using (var stream = new FileStream(newFileName, FileMode.Create))
{
    reader.Close();
    reader = XmlReader.Create(myFile);
    transformer.Transform(reader, new XsltArgumentList(), stream);
}

现在,创建的文件包含所有预期的数据。但是我希望有一种方法可以读取根标签并转换文件,而无需重新整理整个文件。

2 个答案:

答案 0 :(得分:1)

我看不到在XmlReader中重置流的方法。

一种方法是更直接地使用流,如下所示。

  using (FileStream fs = File.Create(myFile))
  {
    var root = new XmlDocument();

    root.Load(fs);

    if (root.DocumentElement.Name == "FC_FeatureCatalogue")
    {
      var xsltDoc = new XmlDocument();
      xsltDoc.Load("myXslt.xsl"));

      XsltSettings xsltSettings = new XsltSettings(false, true);
      var transformer = new XslCompiledTransform();
      transformer.Load(xsltDoc, xsltSettings, new XmlUrlResolver());

      fs.Seek(0, SeekOrigin.Begin);

      using (StreamReader sr = new StreamReader(fs))
      {
        XmlReader reader = XmlReader.Create(sr);
        using (var stream = new FileStream(newFileName, FileMode.Create))
        {
          transformer.Transform(reader, new XsltArgumentList(), stream);
        }            
      }
    }
  }

答案 1 :(得分:0)

我发现了一种灵感来自here的方法。实际上我不需要读取整个文档(如XmlDocument.Load所做的那样)来获取root元素。所以我只是读了读者的第一行:

while (reader.Read()) 
{
    if (reader.NodeType == XmlNodeType.Element) break;
}
if (reader.Name == "FC_FeatureCatalogue")
{
    // ...
}

另外你也可以按照jdweng的建议使用它,这有点短:

reader.MoveToContent();
if (reader.NodeType == XmlNodeType.Element) { ... }

对我来说,只是说虽然读者内部位置现在在文档中的某个位置,但我们可以适当地转换xml。我想这是因为之前读过的元素只是“xml-chunk”,就像xml-declaration或任何注释一样。