Preserve triple-slash in remote URLs (HDFS, file://, ...) in `_as_str` (#7934)

Fixes #7934.

## Summary

`_as_str` routed every non-`xPath` argument — including raw strings — through `xPath(str(path))`, which inherits from `pathlib.PurePosixPath`. PurePosixPath collapses runs of slashes:

```python
>>> str(PurePosixPath("hdfs:///user/path/data.parquet"))
'hdfs:/user/path/data.parquet'
```

`xPath.__str__` then re-inserts `://` via the `SINGLE_SLASH_AFTER_PROTOCOL_PATTERN` substitution, but it can only put exactly **two** slashes back. Triple-slash URIs — HDFS default-host (`hdfs:///path`), `file://`, `smb://`, etc. — lose a slash and silently become a different URL.

That breaks the user's `load_dataset` call:

```python
load_dataset(
    "parquet",
    data_files={"train": "hdfs:///user/path/to/data/train*.parquet"},
    streaming=True,
    storage_options={"host": "hostname"},
)
```

because `xopen(...)` ends up seeing `hdfs://user/path/to/data/...` (host=`user`, path=`path/...`).

## Fix

When the input to `_as_str` is already a `str`, return it unchanged. The pathlib roundtrip was a no-op for paths without backslashes anyway, and it's destructive for triple-slash URIs. `Path` and `xPath` inputs still go through the existing normalization.

```python
def _as_str(path: Union[str, Path, xPath]):
    if isinstance(path, str):
        return path
    return str(path) if isinstance(path, xPath) else str(xPath(str(path)))
```

A deeper fix to `xPath.__str__` itself would also be possible (storing the raw input on construction), but the bug report and every traceback in the issue go through the string path, so this surgical fix matches the reported regression and avoids touching `xPath`'s public surface.

## Reproduce BEFORE/AFTER yourself (copy-paste)

```bash
# --- BEFORE: origin/main, expect slash loss ---
git fetch origin main && git checkout origin/main
python - <<'PY'
from datasets.utils.file_utils import _as_str
print(_as_str("hdfs:///user/path/data.parquet"))  # Expected: hdfs://user/path/data.parquet  (broken)
print(_as_str("file:///etc/hosts"))               # Expected: file://etc/hosts                 (broken)
PY

# --- AFTER: this branch ---
git fetch origin pull/<PR>/head:fix && git checkout fix
python - <<'PY'
from datasets.utils.file_utils import _as_str
print(_as_str("hdfs:///user/path/data.parquet"))  # Expected: hdfs:///user/path/data.parquet  (preserved)
print(_as_str("file:///etc/hosts"))               # Expected: file:///etc/hosts                (preserved)
print(_as_str("hdfs://host/user/path"))           # Expected: hdfs://host/user/path            (still ok)
print(_as_str("s3://bucket/key"))                 # Expected: s3://bucket/key                  (still ok)
PY
```

## What I ran locally

```
pytest tests/test_file_utils.py tests/test_streaming_download_manager.py tests/test_download_manager.py
# 143 + 38 passed (plus the 6 new params)
```

The new parametrized regression test `test_as_str_preserves_remote_url_slashes` fails on `origin/main` with the slash-loss assertion errors above and passes on this branch.

## Edge cases covered

| Input | Pre-fix | Post-fix |
|---|---|---|
| `hdfs:///user/path/data.parquet` | `hdfs://user/path/data.parquet` ❌ | unchanged ✓ |
| `file:///etc/hosts` | `file://etc/hosts` ❌ | unchanged ✓ |
| `hdfs://host/user/path` | unchanged | unchanged |
| `s3://bucket/key` | unchanged | unchanged |
| `https://host.com/archive.zip` | unchanged | unchanged |
| `zip://file.txt::https://host.com/archive.zip` | unchanged | unchanged |

## Notes

- No public API change. `_as_str` is a private helper.
- `Path` and `xPath` inputs are unaffected — pathlib normalization is still applied to them, matching prior behavior.

---

🤖 Disclosure: Authored with assistance from Claude (Anthropic), reviewed and tested by me. Reproducer run on both refs; regression test verified to fail on `origin/main` and pass on this branch.